2

がありUINavigationController、ルート ビュー コントローラーから次のビュー コントローラーにプッシュします。この 2 番目のビュー コントローラーは、初期化とサブビューが大量にあるという点で、かなり「重い」ものです。

私の問題はこれです: トランジション アニメーションがひどく実行されます。基本的に、アニメーションは非常に低いフレーム レートに悩まされます (「プッシュ」アニメーションから合計で 3 ~ 4 フレームを取得します)。

トランジションを手動でアニメーション化する 2 つの方法など、さまざまな手法を試しました。いずれの場合も、アニメーションの最初の 0.4 ~ 0.7 秒は、この低フレームレートの影響を受けます。たとえば、トランジションに 5 秒かかるように設定した場合、最初の 0.5 秒ほどのパフォーマンスは低下しますが、アニメーションの残りの部分は素晴らしくスムーズです。

これにより、移行の開始時に「何か」が発生していると思われます。これにより、デバイスが非常に低いフレームレートでアニメーション化されます。

コードに多くのNSLogステートメントを挿入した後、2 つのことが起こりました。まず、プッシュ中に 2 番目のビューが遅延ロードされていることは明らかです。プッシュを実行する前にビュー プロパティのゲッターにアクセスすることで、これを修正しました。これにより、プッシュ アニメーションが始まる前にすべての初期化が行われることを確認できます。

次に、ほとんどの場合、私のアプリは移行中にメモリ不足の警告を受け取ります。ただし、メモリの警告が表示されない場合でも、アニメーションのパフォーマンスは依然として低く、これらのいずれも原因ではないと思います.

私の質問:UINavigationControllerアニメーションの最初の 0.4 ~ 0.7 秒間だけ、プッシュ トランジション アニメーションで低いフレームレートを経験した人はいますか? それを引き起こす舞台裏で何か他のことが起こっていますか? 何かできることはありますか?

参考までに、ロードして次のビューにプッシュする現在のコードを次に示します。移行前にビューを強制的にロードして初期化するために、意図的にビュー ゲッターにアクセスしています (主にそれを問題として除外するため)。このコードはperformSelectorOnMainThread:::、Web サービス コールバックへの応答として使用するメイン スレッドで実行されます。

PlayingFieldViewController *v = [[PlayingFieldViewController alloc] initWithNibName:@"PlayingFieldView" bundle:[NSBundle mainBundle]];
UIView *lazy = v.view;
[appDelegate.navigationController pushViewController:v animated:YES];
[v release];

他のアニメーション手法もいくつか試しましたが、すべて同じ結果になりました。

CATransition *transition = [CATransition animation];
transition.duration = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[appDelegate.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[appDelegate.navigationController pushViewController:v animated:NO];

と:

[UIView 
  transitionWithView:appDelegate.navigationController.view
  duration:1.0
  options:UIViewAnimationOptionTransitionCurlUp
  animations:^{
   [appDelegate.navigationController pushViewController:v animated:NO];
  }
  completion:NULL];
4

2 に答える 2

4

さらにテストした後、問題を診断することができました。関連する 2 番目のビューには、多数のUIImageViews. これらのビューを削除するか非表示にすると、問題が解決します。

私を失望させたのは、アニメーションの最初の部分だけがフレーム レートの問題に悩まされていたのに対し、アニメーションの残りの部分は完全に滑らかだった (長いアニメーションの場合) という事実でした。これは、すべてのサブビューが存在する場合でも、デバイスがトランジションをスムーズにアニメーション化できることを示しています。

私はまだ iOS 合成の専門家ではありませんが、さまざまなレイヤーが配置されてキャッシュされているため、速度が低下していると推測しています。回避策は、ほとんどのサブビューを非表示にしてビューにプッシュし、ビューが表示されたら別のアニメーションを使用して表示することです。

于 2010-11-30T18:23:28.187 に答える
0

ナビゲーションコントローラーでこれに遭遇したことはありませんが、別のスレッドからテーブルビューを更新するときにほぼ同じ結果が得られました。最初は UI の更新が非常に遅かったのですが、少し遅れてすべてが再び表示されました。Justin がコメントで指摘しているように、メイン スレッドで UI 作業を行う必要があります。これを実現する簡単な方法は、UI への呼び出しを GCD ブロックでラップすることです。

dispatch_sync(dispatch_get_main_queue(), ^{
// Do UI stuff here
});

または使用

performSelectorOnMainThread:withObject:waitUntilDone:

于 2010-11-29T19:09:09.657 に答える