Представить контроллер представления раскадровки из делегата приложения?

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

Но как мне вызвать его из моего делегата приложения?

Нужно ли помещать SignInViewController в мою основную раскадровку? Если да, то как мне получить доступ к моей раскадровке из моего делегата приложения? Или какой-то другой подход лучше?


person Steven Fisher    schedule 19.04.2012    source источник


Ответы (2)


Вы всегда можете ссылаться на свой делегат приложения через синглтон UIApplication. Оттуда вы всегда можете получить свой корневой контроллер представления. С вашим корневым контроллером представления вы можете получить ссылку на раскадровку.

Когда у вас есть раскадровка, все, что вам нужно сделать, это создать экземпляр контроллера представления, который вы хотите. Представьте это.

AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
MainViewController *mvc = (MainViewController *)appDelegate.window.rootViewController;    
LoginViewController *lvc = [mvc.storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[currentVC presentModalViewController:lvc animated:YES];

Может быть более прямой способ получить ссылку на вашу раскадровку, но это почти всегда поможет вам.

person endy    schedule 19.04.2012
comment
Это означает ссылку на контроллер представления, в котором вы сейчас работаете, используя ключевое слово self вместо currentVC. - person Darryl Bayliss; 11.07.2013
comment
но он спросил о представлении из appDelegate, прежде чем попасть в какой-либо контроллер просмотра, я уверен - person Zerho; 18.07.2013
comment
Нет, я этого не делал. Знание того, что мне нужно войти в систему, — это не то решение, которое я могу принять за короткий период времени, который сторожевой таймер iOS позволяет мне настроить мой пользовательский интерфейс. Более серьезная проблема с любого контроллера представления. - person Steven Fisher; 08.07.2014
comment
Проблема с этим ответом заключается в том, что он создает новый контроллер представления, он не дает вам контроллер представления, который, возможно, уже был создан раскадровкой. - person lostintranslation; 03.06.2015

Чтобы показать контроллер представления из любого места (включая делегат приложения), я успешно использовал этот код в iOS 8+ (я не уверен в более ранней совместимости). Он будет представлен в модальном представлении, если оно есть.

YOURAppDelegate *appDelegate =  (YOURAppDelegate *)[[UIApplication sharedApplication] delegate];
UINavigationController *rootNavC = (UINavigationController *)appDelegate.window.rootViewController;
UIViewController *topVC = rootNavC.topViewController;

UIViewController *myNewVC = [rootNavC.storyboard instantiateViewControllerWithIdentifier:<YOUR STORYBOARD ID>];

if (topVC.presentedViewController)
{
    if ([topVC.presentedViewController class] == [UINavigationController class])
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [((UINavigationController*)topVC.presentedViewController) pushViewController:myNewVC
                                                                                animated:YES];
        });
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [topVC.presentedViewController.navigationController pushViewController:myNewVC
                                                                          animated:animated];
        });
    }
}
else
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [rootNavC pushViewController:myNewVC
                            animated:animated];
    });
}

Я обычно оборачиваю это в удобный метод и передаю свой экземпляр контроллера представления. Для OP - вы должны создать SignInViewController в раскадровке, назначить ему уникальный идентификатор раскадровки, а затем заменить этот идентификатор в приведенном выше коде.

person Alexander Gingell    schedule 08.02.2016