简体   繁体   中英

Accessing a view controller created through Storyboard using the App Delegate

I'm working on an iOS5 app using storyboard, and I have a method in a view controller class that i'd like to access from the App Delegate. The trouble is, this view controller gets instantiated via a tab bar controller in storyboard, so the App Delegate has no direct way of calling the method I want...

For a view controller to get in touch with the App Delegate, all one has to do is use:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

Is there a similarly easy way of pointing to an already-instantiated view controller or class?

Thanks to Jerry (above), here's the code that got me what I wanted:

    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *result;

//check to see if navbar "get" worked
if (navigationController.viewControllers) 

    //look for the nav controller in tab bar views 
    for (UINavigationController *view in navigationController.viewControllers) {

        //when found, do the same thing to find the MasterViewController under the nav controller
        if ([view isKindOfClass:[UINavigationController class]])
            for (UIViewController *view2 in view.viewControllers) 
                if ([view2 isKindOfClass:[MasterViewController class]])                    
                    result = (MasterViewController *) view2;
}

I probably would do it in reverse. Create a method in AppDelegate call registerViewController or something. In every ViewController, call the method with itself with a name. Then in AppDelegate, you can do whatever you want afterward. It is messy to do all sort of drill

In AppDelegate

- (void)registerViewController:(NSString *)name controller:(UIViewController *)controller
{
    if(_viewControllers == nil)
    {
        _viewControllers = [[NSMutableDictionary alloc] init];

    }

    [_viewControllers setObject:controller forKey:name];
}

In any ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    [appDelegate registerViewController:@"feelings" controller:self];
}

In AppDelegate

XViewController *vc = (XViewController *)[_viewControllers objectForKey:@"X"];
[X startSpinner];

Hope this help

BS

You'll have to traverse the view hierarchy from the app delegate. Assuming the AppDelegate holds a reference to the UITabBarController , you could use the viewControllers property or selectedViewController property to get to your view controller.

If you are using a storyboard, and you want instance of a viewController in storyboard you can use the following

UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
id viewcontroller = [mystoryboard instantiateViewControllerWithIdentifier:@"identifier"];

Here the 'identifier' is the name provided in the particular viewController's 'storyBoard ID' in 'Identity' section in 'Identity Inspector'.

I have a better solution. You can use window.rootViewController.storyboard to get a reference to the storyboard of that view.

In the AppDelegate, you could simply use indexes to access the controllers via UITabBarController:

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
firstViewController = [[tabBarController viewControllers] objectAtIndex:0];
secondViewController = [[tabBarController viewControllers] objectAtIndex:1];
thirdViewController = [[tabBarController viewControllers] objectAtIndex:2];

Naturally, this will get messed up if you change the ordering of the tab bar. Also, if you're looking for a controller deeper in the hierarchy, you need to do a bit more legwork.

Swift

This is the Swift version of @infiniteLoop's answer.

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewControllerWithIdentifier("identifier") as! MyViewController

You need to replace the storyboard name, view controller name, and view controller identifier with whatever you used in your project.

Related tasks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM