13

私のアプリを iOS 8 でテストして以来、View Controller の初期化とプレゼンテーションの回避策が非常に遅いことがわかりました。

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、ギャップ、提示されたもの) は (明らかに) さらに大きくなります。

次のように通常のものを呼び出すと、プレゼンテーションの遅さも明らかです。

// 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 で親 View Controller の目に見えるフリックなしで直接遷移を実行していた、完全に公正なコードである必要があります。同じことです – 遷移中の親フリックは、両方ともアニメーションなしで処理されます。

誰かがこれを問題として直面していますか?解決策はありますか?UIWindow完璧にトランジットする必要があるものごとに s を使用して陽気な魔法を行う必要なく、これを解決したいと思います。

4

4 に答える 4

1

ルートビューコントローラーを持ち、そこに何かを提示するように要件が制限されているかどうかはわかりません。

しかし、あなたのコードによれば、それは歓迎されているView Controllerのことであり、この場合、このロジックはより便利だと思います。

- (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];

}
于 2015-03-09T13:18:58.683 に答える
0

iOS8 では、完了ブロックで古いプレゼンテーションがまだ完了していないことがわかりました。dismiss または present をすぐに呼び出すと、コンソール メッセージが表示され、present/dismiss が発生しないこともあります。2 番目のプレゼンテーションにさらに遅延実行を追加することで、ある程度の成功を収めました。

 [self dismissViewControllerAnimated:NO completion:^{
         UserProfileViewController *userProfile = ...
         [[NSOperationQueue mainQueue] addOperationWithBlock:^{
             [self presentViewController:userProfile animated:NO];
         }];
    }];
于 2015-01-27T22:04:52.040 に答える