Ручная модальная секция не работает, View Controller не находится в иерархии окон?

Я много часов искал в Интернете и Stack Overflow, и я не могу решить эту проблему. здесь надеюсь, что вы все увидите мою ошибку, потому что я просто не могу ее найти.

У меня есть простое приложение на основе раскадровки, которое я только что начал. Исходный ViewController является экземпляром UITabBarController с двумя пустыми ViewControllers из шаблона. При запуске мне нужно проверить, зарегистрировано ли устройство во внешней службе. Если нет, я покажу modal ViewController, который позволит пользователю пройти аутентификацию, если устройство аутентифицировано, тогда я просто покажу FirstViewController.

Следующие шаги - это все, что я сделал с момента создания проекта:

  • Создайте сцену AuthenticateViewController на раскадровке
  • Создайте файлы кода для AuthenticateViewController и назначьте их соответствующей сцене
  • Создайте файлы кода для подкласса UITabBarController и сопоставьте исходную сцену UITabBarController с этим новым подклассом
  • Создайте новую сцену на раскадровке из сцены UITabBarController на сцену AuthenticateViewController.
  • Вручную вызовите segue из viewDidLoad в подклассе UITabBarController

Когда я запускаю приложение, модальный сегмент не срабатывает, отображается первый ViewController из UITabBarController, и я получаю следующий вывод в XCode:

Warning: Attempt to present <AuthenticateViewController: 0x83c0c10> on <EPTabBarController: 0x83be600> whose view is not in the window hierarchy!

Соответствующий код ниже, на самом деле единственный код, который я добавил до сих пор. Пожалуйста, дайте мне знать, если скриншоты или дополнительная информация будут полезны. Заранее благодарим за помощь.

EPTabBarController, подкласс UITabBarController:

#import "EPTabBarController.h"
#import "AuthenticateViewController.h"

@interface EPTabBarController ()

@end

@implementation EPTabBarController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Ответ 1

Проблема внутри

- (void)viewDidLoad
{
    [super viewDidLoad];    
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

вы пытаетесь представить другое представление (AuthenticateViewController), пока текущий вид (EPTabBarController) еще не загружен в иерархии окон.

Итак, сначала пусть ваш EPTabBarController будет загружен в иерархию окон, а затем представлен AuthenticateViewController.

Попробуйте

- (void)viewDidLoad 
{
    [super viewDidLoad];        
    [self performSelector:@selector(loadAuthenticateViewController) 
               withObject:nil 
               afterDelay:1.0];
}

-(void)loadAuthenticateViewController 
{
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

Ответ 2

Как просто вызвать ваш код в viewDidAppear?

- (void)viewDidAppear
{
    [super viewDidAppear];    
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

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

Любая идея о том, как показать новый модальный формат, не показывая сначала первоначальный вид?

Ответ 3

Когда вы действительно хотите быть под контролем, используйте что-то вроде этого:

@implementation UeInitialisationViewController
BOOL didLoad;
BOOL wantPush;

- (id)init {
    self = [super init];
    if (self) { didLoad = NO; wantPush = NO; }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    didLoad = YES;
    if (wantPush == YES)
        [self performSelector:@selector(pushToMainView) 
                   withObject:nil afterDelay:0.0001];
}

- (void)pushToMainView {
    if (didLoad == YES)
        [self performSegueWithIdentifier:@"pushToMainView" sender:self];
    else
        wantPush = YES;
}
@end

Это приведет к срабатыванию Segue pushToMainView при появлении сообщения [controller pushToMainView], но сдерживается, пока не будет загружено представление.