Подтвердить что ты не робот

IOS 8 - Сбой при представлении диспетчера представлений быстро после установки ключевого окна или увольнения и инсталляции другого

С момента тестирования моего приложения на iOS 8, я обнаружил, что работа над инициализацией и представлением контроллеров представлений очень медленная.

Я работал с кодом, подобным этому на iOS 6 и 7:

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

    [self.window setRootViewController:_rootController];
    [self.window makeKeyAndVisible];

    // Conditions

    if (#first launch condition#) {
        // quite small controller containing Welcome showcase
        WelcomeViewController *w = ....
        [_rootViewController presentViewController:w animated:NO];
    }

    else if (#last opened item condition#) {
        // pretty big container, root view controller contains
        // a grid view which opens Item detail container the same way
        ItemDetailController *item = ....
        [_rootViewController presentViewController:item animated:NO];
    }

}

Это стало действительно вялым ад с iOS 8. Теперь контроллер корневого представления выглядит видимым в течение 0,5-1 секунды, а затем мгновенно перерисовывает экран с представленным. Более того, медленность презентации начала вызывать предупреждение Unbalanced calls to begin/end appearance transitions _rootViewController.

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

[self performSelector:@selector(postAppFinishedPresentation) withObject:nil afterDelay:0];

или что-то в этом роде. Это устраняет проблему небезопасных вызовов, но визуальный пробел (rootviewcontroller, gap, представленный один) становится (очевидно) еще большим.

Медленность презентации также очевидна, когда вы вызываете что-то обычное, как:

// Example: Delegate caught finished Sign In dialog,
//          dismiss it and instantly switch to Profile controller

-(void)signInViewControllerDidFinishedSuccessfully
{
    [self dismissViewControllerAnimated:NO completion:^{
         UserProfileViewController *userProfile = ...
         [self presentViewController:userProfile animated:NO];
    }];
}

который должен быть полностью справедливым фрагментом кода, который использовался для прямого перехода без видимого щелчка контроллера родительского представления на iOS 7. Теперь то же самое - родительский щелчок во время перехода, даже он обрабатывается без анимации.

Кто-нибудь сталкивается с этим как проблема? Любые решения? Я бы хотел решить эту проблему без необходимости делать веселую магию с помощью UIWindow для каждой вещи, в которой я нуждаюсь в безукоризненном прохождении.

4b9b3361

Ответ 1

Я не уверен, что требование ограничено наличием контроллера корневого представления и что-то там присутствует.

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

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

    if (#first launch condition#) {
        // quite small controller containing Welcome showcase
        WelcomeViewController *w = ....

        //It can be navigation or tab bar controller which have "w" as rootviewcontroller
        [self.window setRootViewController:w];
    }

    else if (#last opened item condition#) {
        // pretty big container, root view controller contains
        // a grid view which opens Item detail container the same way
        ItemDetailController *item = ....
        //It can be navigation or tab bar controller which have "item" as rootviewcontroller
        [self.window setRootViewController:item];
    }

    [self.window makeKeyAndVisible];

}

Ответ 2

Если вы используете Storyboard, почему бы не попробовать:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary objectForKey:@"UIMainStoryboardFile"] bundle:[NSBundle mainBundle]];
ViewController *_rootController = [storyboard instantiateViewControllerWithIdentifier:@"root"];
[self.window setRootViewController:_rootController];
[self.window makeKeyAndVisible];
if (vcToShow == 1) {
     ViewController2 *w = [storyboard instantiateViewControllerWithIdentifier:@"vc2"];
    [_rootController presentViewController:w animated:NO completion:nil];
}
else if (vcToShow == 2) {
    ViewController2 *w = [storyboard instantiateViewControllerWithIdentifier:@"vc3"];
    [_rootController presentViewController:w animated:NO completion:nil];
}

Похоже, здесь нет задержки.

Ответ 3

Задержка, которую я получил от пары увольнения/присутствия, была зафиксирована этим. Это может или не поможет вашему экземпляру. Мне пришлось полностью изменить мою стратегию отображения/отклонения контроллеров модального представления в iOS 8:

[_rootViewController presentViewController:vc1 animated:NO completion:nil];

if(iNeedToDisplayVC2) {
     [vc1 presentViewController:vc2 animated:NO completion:nil];
}

Итак, как только я закончил с vc2 позже, я отклоняю vc1 и vc2 в одном вызове. Эта стратегия работает и под iOS 7. Я предполагаю и более ранние версии, но я их не тестировал.

Ответ 4

С iOS8 я обнаружил, что старая презентация еще не завершена еще в блоке завершения, и вызов сразу же уволиться или сейчас может привести к сообщениям консоли, а иногда и настоящая/уловка даже не возникает. У меня был некоторый успех, добавив еще одну задержку во вторую презентацию:

 [self dismissViewControllerAnimated:NO completion:^{
         UserProfileViewController *userProfile = ...
         [[NSOperationQueue mainQueue] addOperationWithBlock:^{
             [self presentViewController:userProfile animated:NO];
         }];
    }];