iOS 8 - 在设置关键窗口后快速显示视图控制器或解除并立即显示另一个视图控制器时出现故障

Mic*_*chi 13 uiviewcontroller ios presentviewcontroller

自从在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];
    }

}
Run Code Online (Sandbox Code Playgroud)

在iOS 8中,这变成了一个非常缓慢的地狱.根视图控制器现在可以看到0.5-1秒,然后立即重新绘制屏幕.此外,演示文稿的缓慢开始引起Unbalanced calls to begin/end appearance transitions _rootViewController警告.

最初的快速提示是通过调用另一个函数来移动这两个条件并以零延迟调用它,以便在下一个主运行循环中处理它:

[self performSelector:@selector(postAppFinishedPresentation) withObject:nil afterDelay:0];
Run Code Online (Sandbox Code Playgroud)

或类似的东西.这解决了unballanced调用问题,但视觉差距(rootviewcontroller,gap,present one)变得(显然)更大.

当您通常称之为以下内容时,演示文稿的缓慢也很明显:

// 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];
    }];
}
Run Code Online (Sandbox Code Playgroud)

这应该是完全公平的代码片段,用于执行直接转换而不会在iOS 7上显示父视图控制器.现在,同样的事情 - 转换过程中的父动画,即使它都是在没有动画的情况下处理的.

有人认为这是一个问题吗?有解决方案吗 我很乐意解决这个问题,而不需要UIWindow为每件我需要完美运送的东西做一些搞笑的魔法.

小智 0

如果您使用情节提要,为什么不尝试:

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];
}
Run Code Online (Sandbox Code Playgroud)

看来这里没有延迟。