Objective-C Monster
Objective-C Monster

Reputation: 57

Push Issue UINavigationController

I am running into an issue when attempting to push from one UINavigationController to another.

I arrive to my CameraViewController - which has am embeded UINavigationController by selecting a button in a different view controller like so:

- (void)goToCamera {
     UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
     CameraViewController *camera = [storyboard  instantiateViewControllerWithIdentifier:@"CameraView"];
     [self presentViewController:camera animated:YES completion:^{
   }];
}

From there I try to go to my PublishViewController by pushing to it - it doesn't have am embeded UINavigationController because I don't think you need one if coming from another UINavigationController.

I try to do this like so:

- (void)goToPublish {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    PublishViewController *publishView = [storyboard instantiateViewControllerWithIdentifier:@"PublishView"];
    [self.navigationController pushViewController:publishView animated:YES];
}

Any ideas why this isn't working? The controller never pushes. Is the embeding still working from when I originally go to my camera or do I ineed to initalize a UINavigationController as well?

Here is my storyboard:

Storyboard

Upvotes: 2

Views: 225

Answers (3)

Suen
Suen

Reputation: 1120

When you present a viewController named VC1, the navigationController of VC1 must be nil unless you present a navigationController.

You should know vc.navigationController is not nil when someone(UINavigationController) push it, or it is the rootViewController of UINavigationController.(In fact, the nav's rootViewController is also be pushed to the nav's stack).

You should create a new navigationController.

- (void)goToCamera {
     UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
     CameraViewController *camera = [storyboard  instantiateViewControllerWithIdentifier:@"CameraView"];
     UINav *nav = UINav alloc]initWithRootVC:camera];
     [self presentViewController:nav animated:YES completion:^{
   }];
}

Upvotes: 1

Glen T
Glen T

Reputation: 1560

I believe the problem here is that when you initialize a UIViewController by identify you only get the instance of that view controller and not the UINavigationController it is embedded in.

To solve your problem you will need to instantiate and present the Navigation Controller (which embeds the CameraViewController).

Although there are many ways to do this, I suggest you consider moving away from explicitly calling [storyboard instantiateViewControllerWithIdentifier:] and instead do the following:

  1. Set your navigation controller (or initial app view controller) to the 'Initial View Controller'. E.g.

enter image description here

  1. Add a segue between the CameraViewController, and PublishViewController (see here for details on how to do this https://developer.apple.com/library/ios/recipes/xcode_help-IB_storyboard/chapters/StoryboardSegue.html ).

  2. If you didn't connect the segue directly to a button you set the 'Storyboard segue identify' in Interface Builder can manually trigger it via a call to performSegueWithIdentifer: e.g.

    - (void)goToPublish {
            [self performSegueWithIdentifier:@"Go To Publish" sender:self];
    }
    

This approach will ensure the UINavigationController is correctly initialize, and also result in less code which is usually a win :).

Upvotes: 0

John Stephen
John Stephen

Reputation: 7734

That looks fine to me, so I suspect you have a nil object in there. Add some asserts to ensure you're dealing with objects where you expect them:

- (void)goToPublish {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    assert(storyboard);
    PublishViewController *publishView = [storyboard instantiateViewControllerWithIdentifier:@"PublishView"];
    assert(publishView);
    assert(self.navigationController); // this is probably the cause
    [self.navigationController pushViewController:publishView animated:YES];
}

I think the pushViewController message would barf if you gave it a nil view parameter, so I think the primary suspect is the self.navigationController.

Upvotes: 1

Related Questions