Stretch
Stretch

Reputation: 3759

Accessing view controllers programmatically

New to iOS development, I've been following the tutorials on developer.apple.com, and am now adding functionality to those examples to further my knowledge.

The "second ios app" tutorial gives you a navigation controller based app. Extending this app, I want to have a tab bar controller as the first view controller.

So I now have the following setup:

Storyboard

All good. But there is code in the BirdsAppDelegate (a UIApplicationDelegate) which was relying on the navigation controller being the root view controller, so it can create and assign the "datacontroller" object.

This is the original code (before I added the tab bar controller):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    BirdsMasterViewController *firstViewController = (BirdsMasterViewController *)[[navigationController viewControllers] objectAtIndex:0];

    BirdSightingDataController *aDataController = [[BirdSightingDataController alloc] init];
    firstViewController.dataController = aDataController;
    return YES;
}

Now this code fails because it assumes the root view controller is the navigation controller.

I have updated the code so that it works - but in my opinion it is ugly, and would have to be changed every time I make a change to the view controller hierarchy:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    UITabBarController *tabBarController =  (UITabBarController *)self.window.rootViewController;

    UINavigationController *navigationController = (UINavigationController *)    [[tabBarController viewControllers] objectAtIndex:0];

    BirdsMasterViewController *firstViewController = (BirdsMasterViewController*) [[navigationController viewControllers] objectAtIndex:0];

    BirdSightingDataController *aDataController = [[BirdSightingDataController alloc] init];

    firstViewController.dataController = aDataController;

    return YES;
}

So my question is: What is the better way to do what I am doing in the code above, so that any changes to the hierarchy will not break the code?

How do I programmatically access the view controller I am after in the application delegate, so that I can create and assign it's BirdSightingDataController object?

Thanks!

Upvotes: 2

Views: 947

Answers (2)

Hubert Kunnemeyer
Hubert Kunnemeyer

Reputation: 2261

You don't even need that code at a all. If you just want to change the controller, go to the storyboard and select the viewController you want to change to a TabBarController. In the Editor menu, there is an option for "Embed In", the choices are TabBar and Navigation controllers.

enter image description here

I always start with a single view application template. There is no code in the "application didFinishLaunchingWithOptions:" method,(except to return YES). You can set any viewController as your initial view in the storyboard, by setting the is initial View Controller check box, or just dragging the arrow to the viewController you want as your initial view.

Is Initial View

Upvotes: 0

fbernardo
fbernardo

Reputation: 10124

You can loop the [navigationController viewControllers] array looking for an instance of BirdsMasterViewController... Using [obj isKindOfClass:[BirdsMasterViewController class]].

Upvotes: 1

Related Questions