AndrewSB
AndrewSB

Reputation: 951

Not understanding how the NavigationController and UIViewControllers are working in iOS

I have a project which I don't really understand the views and navigation behind. I start out in the AppDelegate (MAAppDelegate), where I define properties:

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIViewController *detailViewController;

Then in the MAAppDelegate.m, I create a navigationController, and

@implementation MAAppDelegate
@synthesize detailViewController;
@synthesize window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Init the navController for the Master Detail View of the grade cells

    UINavigationController *navController = [[UINavigationController alloc] init];


    detailViewController = [[UIViewController alloc] init];

    UIViewController *viewController = [[MAController alloc] init];

    navController = [[UINavigationController alloc] initWithRootViewController:viewController];

    self.window.rootViewController = viewController;

    [self.window makeKeyAndVisible];

    return YES;
}

So at this point, I think I have a working naviationController, I've setup an instance of a custom UIViewController (custom class MAController) and I've set it up as the rootViewController.

Then, in my MAController class, the class where I do all of my UI stuff (the entire UI is done programmatically, no nibs or storyboards). Here is a bit of the viewDidLoad of MAController:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.


    [self.navigationController setNavigationBarHidden:YES]; // I commented this line out and realized it does nothing

I go on (in viewDidLoad) to add a bunch of subviews to self.view, like this

[self.view addSubview:self.backgroundImageView];

Earlier, I created a viewController in the AppDelegate class and it was called view, so I assumed it was refereeing to that but now since I've changed it (in AppDelegate) to viewController, I guess I was thinking wrong?

And then finally, I create a UIView in 'viewDidLoad`:

UIView *header = [[UIView alloc] initWithFrame:headerFrame];
header.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = header;

and start adding a bunch of subviews to this new UIView I created header.

So, in short, I have no idea what is happening. Later, when I tried telling (from a method inside MAController) self.navigationController (which I assumed to be navigationController in charge of everything in my project - created at the beginning in the AppDelegate) to pushViewController a new viewController that I was going to use as a detailView for a table, it got weird.

So I'm just trying to understand what has control, and what the rootViewController is, and just what is happening.

Upvotes: 0

Views: 124

Answers (2)

EhTd
EhTd

Reputation: 3270

The main window root is set to a view controller and not the navigation controller

Change:

self.window.rootViewController = viewController;

to:

self.window.rootViewController = navController;

EDIT:

You can access the navigationController from anywhere by asking your appDelegate. It is normally not considered a good practice:

MAAppDelegate *delegate = (MAAppDelegate *)[[UIApplication sharedApplication] delegate];
UINavigationController *nav = delegate.navigationController;

Don't forget to:

#import "MAAppDelegate.h"

Upvotes: 1

Aaron
Aaron

Reputation: 7145

First, take a little time and read through how navigation controllers work. The documentation is really helpful:

https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html

Second, your problem is that your window's root view controller is not the navigation controller you created. Rather it is an instance of MAController. This is what you're doing:

UIViewController *viewController = [[MAController alloc] init];

// some other code ...

self.window.rootViewController = viewController;

I think you meant to add MAController as the root view controller of the navigation controller and make the navigation controller your window's root. If so, you'll want to set your view controllers up like this:

UIViewController *viewController = [[MAController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = navController;

Another potential problem is that you don't seem to be doing anything with your detailViewController. Maybe that's confusing you too.

Upvotes: 1

Related Questions