views:

736

answers:

3

I have a UIViewController subclass that accesses self.navigationController in viewDidLoad:. Depending on where it is in the view stack, I will either get the navigationController or I will get nil.

If my stack is "RootViewController -> MyViewController", I get a valid pointer.

If my stack is "RootViewController -> AnotherViewController -> MyViewController", I get nil.

In both cases, MyViewController is being pushed onto the stack with:

[self.navigationController pushViewController:self.myViewController 
                           animated:YES];

This has me stuck, because I need to be able to push another ViewController on the stack above MyViewController, which works fine in the first case but obviously fails on the second.

A: 

Hi Travis, from everything I can see the UIViewController's self.navigationController is designed to always return the appropriate UINavigationController as long as the UIViewController exists within a UINavigationController's stack. This is probably one of those cases that I seem to run into myself more often than I'd like where a simple coding error is masquerading as something much more complex. In these cases I usually have good luck setting up an entirely new Xcode project with the minimal code needed to reproduce the issue and more times than not in that process I find a fix for something I overlooked that can then be easily applied in the main project. I'm sorry I can't offer more specifics but what you are describing seems to go against the design of the Cocoa Touch framework and if you can still reproduce it in a minimal Xcode project written in strict accordance with the documentation it may be a good idea to file a bug report with Apple. Hopefully though you will just find something simple you overlooked and be kicking yourself in a few minutes =)

Adam Alexander
This was essentially the problem. The dual-edged sword of nil swallowing messages sent to it. :) Taking a couple days off and coming back is amazingly useful to find problems like this.
Travis Jensen
A: 

Hi Travis, this is exactly the same problem I'm having. Any chance you found a solution?

update: Possible something is wrong the XIB and controller setup. I did however created a class with static variables to coordinate the navigation. Once initialized with statically in the RootViewController I can now access the navigationControl from with the static variable not with the inner tableViewController's self.navigationController.

Sigh... Still it is frustrating to not know what you are doing exactly.

Proclus
Unfortunately, I can't say for sure what I did that fixed it. I think what was happening was that the event I was checking to see if I should push the new controller was getting called twice. I took my pushViewController() call and wrapped it with an "isAlreadyPushed" flag (and other associated logic) and it seemed to fix it.
Travis Jensen
A: 

What I usually do is subclass UIViewController and add a method to set the navigationController. There's no reason not to have this as read/write, especially considering how often Apple's classes will decide not to set the navigationController (or the parentController, for that matter) even if they are in the same stack.

anktastic