1

I have a UIViewController subclass(Say BBB) that inherited from already written custom UIViewController class(Say AAA). The BBB class have a UITableView in it and when the user tap on any cell of the UITableView, I want to push another UIViewController class(Say CCC).

So, I tried to push the CCC controller in BBB's tableView: didSelectRowAtIndexPath: method.

My code is,

CCC *ccc = [[CCC alloc] init];
[self.navigationController pushViewController:ccc animated:YES];
[ccc release];

Nothing happens when tapping the cell, so I checked the naviagtion controller of class BBB by the following code.

if (self.navigationController == nil)
{
    NSLog(@"Navigation controller is nil");
}

The message was printed successfully :) So, I tried to assign some thing to navigation controller and my bad luck, it is a read-only property.

Then I tried to make a local UINavigationController by assigning ccc as it rootviewcontroller and then tried to push that local navigation controller. It throws an exception "Pushing the same view controller instance more than once is not supported".

My questions are,

  • Is it possible to find where the navigation controller get nil value in AAA class? I did not make navigation controller as nil in my BBB class, and I find whether any statements like "self.navigationController = nil" in class AAA. But nothing is like that.

  • How can I push the CCC class?

Thanks

Confused
  • 3,846
  • 7
  • 45
  • 72
  • What is the root view controller of your window? Is it AAA or BBB, or something else? Are you using storyboard or xib, or doing everything in code? – rdelmar Dec 12 '12 at 18:56
  • My root view controller is another controller (say DDD). I'm doing all this by code only. – Confused Dec 12 '12 at 19:06

2 Answers2

1

Put this into your app delegate and the first version of your code should work.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self.window makeKeyAndVisible];
    AAA *aaa = [[AAA alloc] init];
    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: aaa];
    [self.window makeKeyAndVisible];

    return YES;
}
bert
  • 1,556
  • 13
  • 15
  • There are so many assignments to self.window.rootViewController in my AppDelegate method. I'm wondering the concept why presentModalViewController: method working without any problem? why not pushViewController? – Confused Dec 12 '12 at 19:28
  • the documentation for UIViewController.navigationController says "The nearest ancestor in the view controller hierarchy that is a navigation controller. (read-only)" If there is no navigation controller in the hierarchy - meaning you did not add one - it will be nil and everything you invoke on it does not work. So if you're doing [self.navigationController pushViewController:vc] it will not work. Set the navigation controller as the root view controller. Then add your other viewControllers to it and their property 'self.navigationController' will be set and pushViewController will work. – bert Dec 13 '12 at 21:54
0

To get the self.navigationController property to be properly set, you'll have to create a UINavigationController with [[UINavigationController alloc] initWithRootViewController: aaa]. Then wherever you're adding aaa currently (a splitViewController, or to the UIWindow, etc.), instead use the navigation controller you create.

For example, if you're setting up the views using code, in your app delegate:

AAA *aaa = [[AAA alloc] init];
UINavigationController *root = [[UINavigationController alloc] initWithRootViewController: aaa];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window makeKeyAndVisible];
window.rootViewController = root;

Now, aaa.navigationController will point to root, and so you can do what you had in your original post: [self.navigationController pushViewController: bbb animated: YES];

cscott530
  • 1,658
  • 16
  • 25
  • My root view controller was another class. Assuming that class as DDD, I create a instance of that class say ddd, then tried the way you told. It throws the same error :( – Confused Dec 12 '12 at 19:13
  • @Confused updated the post. can you add DDD to a navigation controller, as in my sample? Sou'll have a nav controller which contains ddd, then it pushes on aaa, which can then push on bbb? – cscott530 Dec 12 '12 at 19:16
  • Tested again and when I tap on the table cell, it shows the AAA controller (but does not shows what I defined in CCC class). Also the transition done without any animation even if I mentioned the animated property to YES. – Confused Dec 12 '12 at 19:24
  • Hi, the problem is, when I present BBB class from DDD class, I just present the BBB's instance without navigation controller. So the navigation controller is set nil and I can not push CCC from BBB. Thanks for your time.. :) – Confused Dec 13 '12 at 07:13