Lucabro Lucabro - 3 months ago 19
iOS Question

UINavigationController is nil after pop

My project is complex (a bit too much probably) but the question is simple, here's the code

...
self.vc = [[ClassName alloc] init];
if ([[self.navigationController.viewControllers lastObject] isKindOfClass:[ClassName class]]) {
[self backAndGo:self.vc title:@"Title"];
}
else {
[self vai:self.vc title:@"title"];
}
...


in this code i've to go directly in the next view if the current view is different than
ClassName
, otherwise go back of 1 view and the go to the next.

- (void)backAndGo:(id)view title:(NSString *)title

- (void)backAndGo:(id)view title:(NSString *)title
{
NSLog(@"before %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);

[self.navigationController popViewControllerAnimated:NO];

ALCParentViewController *viewController = (ALCParentViewController *)view;
[self.navigationController pushViewController:viewController animated:YES];

NSLog(@"after %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);
}


ALCParentViewController is a parent class of vc, in this method the first log of navigatin controller is correct with all the stack of viewcontrollers, and the
popViewController
is executed but in the second log navigationController is null with 0 element obviously, and the
pushViewController
method is not executed, why? any ideas?

- (void)vai:(id)view title:(NSString *)title

- (void)vai:(id)view title:(NSString *)title
{
ALCParentViewController *viewController = (ALCParentViewController *)view;
[self.navigationController pushViewController:viewController animated:YES];
}


This is instead the other method to reach directly the second view, and it works correctly, another courius thing (almost for me) is that dispite the nil pushviewcontroller, navigation (push and pop) in other view works correctly...

EDIT 1:

As lucaslt89 said i've put a breakpoint in the second log and make "po self.navigationController" in the consolle, here the result

(lldb) po self.navigationController
$0 = 0x00000000 <nil>
(lldb)


it's nil, but i can see that in the log without breakpoint...

EDIT 2:

(lldb) po self.navigationController
$0 = 0x099787d0 <UINavigationController: 0x99787d0>
(lldb) po auxNavController
$1 = 0x099787d0 <UINavigationController: 0x99787d0>
(lldb)


after operations suggested by lucaslt89, the two address are the same

Answer

According to your last edit, one solution is to hold a reference to the navigation controller. Your backAndGo method should be like that

- (void)backAndGo:(id)view title:(NSString *)title
{
    NSLog(@"before %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);

    UINavigationController *auxNavController = self.navigationController;

    [self.navigationController popViewControllerAnimated:NO];

    ALCParentViewController *viewController = (ALCParentViewController *)view;
    [auxNavController pushViewController:viewController animated:YES];

    NSLog(@"after %@,%d",[auxNavController viewControllers],[[auxNavController viewControllers] count]);
}

If you debug that, the address of self.navigationController prior to the pop should be the same as the auxNavController after the pop. Try that and tell us your results!