Check to see if UIViewController has already been created - objective-c

I'm trying to check if a viewcontroller has already been created. If the view already exists then it should become the current view. If it doesn't exist then it should be created and made visible.
My code is
DemoViewController *demoController = [DemoViewController alloc];
for(DemoViewController *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[DemoViewController class]])
{
viewExists=true;
demoController=view;
}
}
if (!viewExists) {
demoController initWithNibName:#"DemoViewController" bundle:nil;
}
[view release];
[demoController release];
I'm not sure where I'm going wrong but it would appear that the for loop isn't being executed.
Any help would be great!

Try like this:
DemoViewController* demoController = nil;
for(int vv=0; vv<[self.navigationController.viewControllers count]; ++vv) {
NSObject *vc = [self.navigationController.viewControllers objectAtIndex:vv];
if([vc isKindOfClass:[DemoViewController class]]) {
demoController = (DemoViewController*)vc;
}
}
if (demoController == nil) {
demoController = [[DemoViewController alloc] initWithNibName:#"DemoViewController" bundle:nil];
// Do we need to push it into navigation controller?
}
[demoController release];

Related

Why is my storyboard not loaded?

I am trying to open a separate storyboard using code for a specific login task.
I created the storyboard and the instance class as follows
+ (instancetype)newStoryboardInstance {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:NSStringFromClass([self class]) bundle:[NSBundle bundleForClass:[self class]]];
AdyenLoginViewController *viewController = [storyboard instantiateInitialViewController];
return viewController;
}
I am then calling this from another class like this
- (void) viewDidAppear:(BOOL)animated {
if([NWTillHelper isDebug] == 1) {
NSLog(#"%s entered", __PRETTY_FUNCTION__);
}
[AdyenLoginViewController newStoryboardInstance];
}
But the loginController is never shown and no error messages are shown, it just finishes loading my normal storyboard and then stops.
The storyboard name etc is correct as per the class name and no compiler errors or warnings are shown
How can I make it load my specific storyboard?
If you are using navigation controller then viewDidAppear will look like this :-
- (void) viewDidAppear:(BOOL)animated {
if([NWTillHelper isDebug] == 1) {
NSLog(#"%s entered", __PRETTY_FUNCTION__);
}
if([AdyenLoginViewController newStoryboardInstance]) {
[self.navigationContoller pushViewController:[AdyenLoginViewController newStoryboardInstance] animated:true];
}
}
Or you can present the viewController like this :-
- (void) viewDidAppear:(BOOL)animated {
if([NWTillHelper isDebug] == 1) {
NSLog(#"%s entered", __PRETTY_FUNCTION__);
}
if([AdyenLoginViewController newStoryboardInstance]) {
[self presentViewController:[AdyenLoginViewController newStoryboardInstance] animated:true completion:^{
}];
}
}

Unable to Get View Class in the top

I am trying to get current view open in my code using this code in delegate while handling Push Notification
NSArray *views = window.subviews;
NSLog(#"views: %#", views);
UIView *topview=[views lastObject];
when is click on topview and see using below tool (eye mark) it shows the current view
open .
But when i am try to get its kind of class using below two method none of these work
for(UIView *view in window.subviews)
{
if([view isKindOfClass:[MyClass class]])
{
NSLog(#"view is a MyClass\n");
}
}
or
if ([topview isKindOfClass:[MyClass class]])
{
NSLog(#"topview is a MyClass\n");
}
else
{
NSLog(#"topview is NOT a MyClass\n");
}
How can i get my visible view name of kind of class.
self.navigationController.viewControllers returns a UIViewController* array, not a UIView* array.
So, for your first solution:
for(UIViewController *viewController in self.navigationController.viewControllers)
{
if([viewController.view isKindOfClass:[MyClass class]])
{
NSLog(#"view is a MyClass\n");
}
}
will work.
For the visible UIViewController*, you can use:
UIViewController* viewController = self.navigationController.visibleViewController;
For the topmost view:
UIView* topmostView = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];

When are interface builder IBOutlet objects created

I am using the iPad master / detail project template and I'm trying to update some UILabels in the detailViewController when the app is first run.
Here is My Code :
(void)setObject:(id)newObject
{
if (_object != newObject) {
[_object release];
_object = [newObject retain];
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
[self updateDetails];
}
- (void) updateDetails
{
NSLog(#"Details = %#", self.details);
NSLog (#"detailLabel %#", self.detailLabel);
self.detailLabel.text = [self.details objectForKey:#"aKey"];
}
- (IBAction)refresh:(UIBarButtonItem *)sender {
[self updateDetails];
}
setEvent is called from the Master View Controller's viewDidLoad method as selecting it's tableview's 1st row as a default.
if (![self.tableView indexPathForSelectedRow])
{
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:0];
[self.detailViewController setObject:[self.sortedObjects objectAtIndex:0]];
}
When I run the code the detailLabel is not changed and the NSLog says self.detailLabel is (null). If 'refresh' is called later from a button click detailLabel is not null and updates correctly. How can I do this to make sure the detailLabel has been created and is not (null)?
The IBOutlet objects will be created at the time of viewDidLoad() of that object(detail view, but not master view).
call the [self updateDetails]; in viewdidLoad() method of detail view controller to avoid this problem.

Paging a TableView, but DataSource/Delegates not executing

I am having problems with getting the datasource or delegate methods to execute.
I am using a Paging View in my MainViewController and it pages just fine, but when it comes to the tableview is blank and when I put a breakpoint where the datasource methods are, it never gets called.
MainViewController to Load the View
if ((NSNull *)controller2 == [NSNull null])
{
if(page == 2)
{
controller2 = [[requestDetailThreeViewController alloc] initWithRequestNumber:[request objectForKey:#"RequestID"]];
[viewControllers replaceObjectAtIndex:page withObject:controller2];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * 2;
frame.origin.y = 0;
controller2.view.frame = frame;
[scrollView addSubview:controller2.view];
}
}
The TableViewController (requestDetailThreeViewController)
- (void)viewDidLoad
{
[super viewDidLoad];
[History fullHistoryWithBlock:^(NSArray *netMessages, NSError *error) {
if (error) {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error", nil) message: [error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(#"OK", nil), nil] show];
} else {
NSLog(#"Number of Historical Entries: %d", [netMessages count]);
self.historyFromNet = [NSMutableArray arrayWithArray:netMessages];
}
} forID:requestNum];
}
- (id) initWithRequestNumber:(NSString *)requestID
{
if (self = [super initWithNibName:#"View" bundle:nil])
{
self.requestNum = requestID;
}
return self;
}
(Apologize for the spacing on the 2nd block of code, hard time getting it into code mode.
It executes these two methods, but it doesn't execute the datasource methods I also have in the class.
In the XIB file I have the owner of the xib set to the requestDetailThreeViewController
The tableView is set to datasource/delegate and view
If I set the tableview to hidden in the ViewDidLoad, it does disappear.
I just can't get it to execute the methods to populate the table.
Update:
Some more information-
The View XIB only has a TableView in it, no controllers.
Thanks!
Alan
You are adding a child view controller so you will need to use the UIViewController containment methods.
Something like:
controller2 = [[requestDetailThreeViewController alloc] initWithRequestNumber:[request objectForKey:#"RequestID"]];
[viewControllers replaceObjectAtIndex:page withObject:controller2];
[self addChildViewController:controller2];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * 2;
frame.origin.y = 0;
controller2.view.frame = frame;
[scrollView addSubview:controller2.view];
[controller didMoveToParentViewController:self];
}
Also consider using a UIPageViewController for a paging view rather than doing it manually via a scroll view
You can try to set self.tableView.delegate = self in -(void)viewDidLoad
that is
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.delegate = self;
}

Check if controller has already been loaded XCode

I have the following code to push a new ViewController in a Split View Controller:
Level4ViewController *controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
The only problem I have, if I were to run this again, a new controller will show, I would like to be able to go to the view that I had before with all my data.
Can anyone help me out here.
Thanks.
EDIT:
Updated code?
Level4ViewController *controller;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
controller = view;
if(controller == nil)
{
controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
}
else {
controller = [self.navigationController.viewControllers objectAtIndex:1];
}
}
}
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
UINavigationController has a property viewControllers which is a NSArray that hold all the stack that has been pushed to the navigation controller, in this array you can check for your view controller if it is there use that one - you check like this -
Level4ViewController *lvc;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
lvc = view;
}
}
and if you already knows that at which index your viewcontroller is there then you can get it from that index as -
Level4ViewController *lvc = [self.navigationController.viewControllers objectAtIndex:1];
update -
Level4ViewController *controller;
for(UIView *view in self.navigationController.viewControllers)
{
if([view isKindOfClass:[Level4ViewController class]])
{
controller = view;
}
}
if(controller == nil)
{
controller = [[Level4ViewController alloc] initWithNibName:#"ModuleViewController" bundle:nil];
}
[[detailViewController navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
If you are using a navigation controller
FirstScreenViewController *firstScreenVC = [self.storyboard instantiateViewControllerWithIdentifier:#"1S"];
if (![self.navigationController.topViewController isKindOfClass:FirstScreenViewController.class])
[self.navigationController pushViewController:firstScreenVC animated:YES];