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

时间:2014-09-22 15:23:33

标签: ios uiviewcontroller presentviewcontroller

自从在iOS 8上测试我的应用程序以来,我发现有关视图控制器初始化和演示的工作真的很慢。

我曾经在iOS 6&amp ;;上使用与此类似的代码。 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];

或类似的东西。这解决了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];
    }];
}

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

有人认为这是一个问题吗?有解决方案吗我很乐意解决这个问题,而不需要为UIWindow s做一些有趣的魔法,因为我需要完美无缺地运送每一件事。

4 个答案:

答案 0 :(得分: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];

}

答案 1 :(得分:0)

如果您使用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];
}

看起来这里没有延迟。

答案 2 :(得分:0)

我从解雇/现在对的延迟是由此确定的。它可能会或可能不会帮助您的实例。我不得不完全改变我在iOS 8下显示/解除模态视图控制器的策略:

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

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

所以一旦我以后完成vc2,我会在同一个调用中关闭vc1和vc2。此策略也适用于iOS 7。我也假设早期版本,但我没有测试它们。

答案 3 :(得分:0)

使用iOS8,我发现旧的演示文稿在完成块中还没有完成,并且立即调用dismiss或present会导致控制台消息,有时甚至不会出现现在/解除。通过在第二个演示文稿中添加进一步延迟演奏,我取得了一些成功:

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