Доступ к контроллеру представления, созданному через раскадровку, с помощью делегата приложения - PullRequest
14 голосов
/ 09 января 2012

Я работаю над приложением iOS5, использующим раскадровку, и у меня есть метод в классе контроллера представления, к которому я хотел бы получить доступ из Делегата приложения. Проблема в том, что этот контроллер представления создается с помощью контроллера панели вкладок в раскадровке, поэтому у App Delegate нет прямого способа вызвать метод, который я хочу ...

Чтобы контроллер представления мог связаться с делегатом приложения, все, что нужно сделать, это использовать:

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

Есть ли такой же простой способ указать на уже созданный экземпляр контроллера или класса представления?

Ответы [ 7 ]

15 голосов
/ 09 января 2012

Спасибо Джерри (выше), вот код, который дал мне то, что я хотел:

    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;
}
10 голосов
/ 04 ноября 2012

Я бы сделал это наоборот. Создайте метод в AppDelegate, вызовите registerViewController или что-то еще. В каждом ViewController вызывайте метод с самим именем. Затем в AppDelegate вы можете делать все, что захотите. Грязно делать все виды упражнений

В AppDelegate

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

    }

    [_viewControllers setObject:controller forKey:name];
}

В любом ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

В AppDelegate

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

Надеюсь, эта помощь

BS

10 голосов
/ 09 января 2012

Вам придется пересмотреть иерархию представления из делегата приложения. Предполагая, что AppDelegate содержит ссылку на UITabBarController, вы можете использовать свойство viewControllers или selectedViewController, чтобы получить доступ к контроллеру представления.

7 голосов
/ 23 января 2014

Если вы используете раскадровку и вам нужен экземпляр viewController в раскадровке, вы можете использовать следующее

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

Здесь «идентификатор» - это имя, указанное в «storyBoard ID» конкретного viewController в разделе «Identity» в «Identity Inspector».

6 голосов
/ 16 ноября 2012

У меня есть лучшее решение.Вы можете использовать window.rootViewController.storyboard, чтобы получить ссылку на раскадровку этого представления.

2 голосов
/ 26 октября 2012

В AppDelegate вы можете просто использовать индексы для доступа к контроллерам через UITabBarController:

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

Естественно, это испортится, если вы измените порядок панели вкладок. Кроме того, если вы ищете контроллер глубже в иерархии, вам нужно сделать немного больше работы.

1 голос
/ 18 июня 2016

Swift

Это Swift-версия ответа @ infiniteLoop.

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

Вам необходимо заменить имя раскадровки, имя контроллера представления и контроллер представленияидентификатор того, что вы использовали в своем проекте.

Связанные задачи

...