更新: 最初にこの質問に対する私の回答を参照してください。これはバグのようです。最小限のテスト ケースが作成され、レポートが Apple に提出されました。(iPhone OS 3.1 で修正されました。)
これは「I'm so close!」の謎解きです。デパートメント。
Tab Bar ベースの iPhone アプリがあります。各タブには、通常の容疑者 (ナビゲーション バー、テーブル ビューなど) を含むUINavigationControllerがあり、別の VC につながる可能性があります。
現在、これらの下位レベルの VC の 1 つが、ポートレートモードとランドスケープ モードで使用されます。しかし、問題があります。ランドスケープに適した VC のshouldAutorotateToInterfaceOrientation:は、そのままでは呼び出されません。何をすべきか?
これが私たちの仕事です。独自のファイルに実装したタブバーコントローラーには、次のものがあります。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
これにより、ランドスケープに適した VC にリクエストが伝達され、VC もこのメッセージに応答します。私の他のすべての VC はこの方法を実装していないため、デフォルトの縦向きのままです。
問題が解決しました!!!わーい!
まあ、そうではありません。:(
タブ バー コントローラーのMoreNavigationControllerの奥からランドスケープ フレンドリーな VC が呼び出されると、うまくいかないようです。
最初の 4 つのタブ バーUINavigationControllersのいずれかから呼び出された VC と、 MoreNavigationController内から呼び出された同じ VCを比較/対照することにしました。これは少し超詳細になるので、我慢してください。うまくいけば、プレイバイプレイが物事を解明するのに役立つことが証明されます.
アプリが読み込まれると、タブ バー コントローラーの shouldAutorotate... メソッドへの最初の呼び出しがいくつかあります。これらの初期のケースでは、selectedViewControllerは nil です。しかし、最終的に読み込みを終了し、最初のタブ項目が選択され、すべてが順調です。
右。まず、最初の 4 つのタブ バー項目の 1 つを選択し、VC にドリルダウンします。
3 番目のナビゲーション バー項目を選択します。これが 3 番目のナビゲーション コントローラーです。ローテーションをサポートする VC にドリルダウンします。簡単に調べると、親が確かにタブ バーのビュー コントローラー リストの 3 番目のナビゲーション コントローラーであることが確認されます。良い!
デバイスを回転させてみましょう。タブ バー コントローラーは自動回転するように求められます (上記のコードを参照)。selectedViewControllerは3 番目のナビゲーション コントローラーでもあり、さらにナビゲーション コントローラーの上部と可視のビュー コントローラーの両方が、回転をサポートする信頼できる VC に設定されていることがわかります。
したがって、タブ バー コントローラーはshouldAutorotateメッセージを 3 番目のナビゲーション コントローラーに転送しますが、回転に適した VC が最終的にメッセージを受け取ります。(ここでは特別なことはしていません。目的の VC がメッセージを受け取るのは、それが一番上または可視の VC であるためでしょうか?) いずれにせよ、横向きに回転し、サイズが変更され、すべてがうまくいきます。"大成功!"
戻るボタンを押して VC スタックをポップし、ランドスケープ モードを途中で終了します。タブ バー コントローラーが再度照会されます。
ここで少し脇に置いておきます。ナビゲーション コントローラーのtopViewControllerは依然として回転に適した VC ですが、visibleViewControllerはUISnapshotModalViewControllerに設定されています。へー。これは前に見たことがありません...しかし、エリカ・サドゥンは持っています。「消えるビューコントローラー」用のようです(この場合は確かに真実です-大丈夫です)。
ステップを進めていくと、目に見える VC はスナップショットのままですが、特別な VC が最終的になくなるため、最上位の VC は最終的にスタック上の次の VC に変更されます。けっこうだ。
これが、すべてがうまく機能するシナリオです。
今度は、同じテストを試してみましょう。今回は、MoreNavigationController ([その他] タブ バーの項目) に移動し、前と同じ VC クラスにドリルダウンします。私の場合、たまたまタブ バー コントローラーの VC リストの 7 番目です。
ローテーション対応の VC に入ると、今度は直接ローテーションするように求められます。Tab Bar Controller は、回転の許可をまったく求められません。うーん。
親 VC を簡単に確認すると、それがMoreNavigationControllerであることがわかります。わかりました、それは理にかなっています。
それでは、デバイスを回転させてみましょう。何も呼び出されません。ブレークポイントにはヒットしません。私たちのVCにはありません。タブバーコントローラーにはありません。(は?!?!)
ああああああ。スタックをポップして、同じ VC に戻り、再度ローテーションを試みます。変。ここで、Tab Bar Controller で、自動回転の許可を求める呼び出しを受けます。ここで、選択された Controller は信頼できる Nav コントローラー (#7) ですが、今回はそのvisibleViewControllerとtopViewControllerがNILに設定されています。
ここから続行すると、デバッガー コンソールに謎のメッセージが表示されます。
二段回転アニメーションを使用。よりスムーズなシングル ステージ アニメーションを使用するには、このアプリケーションで 2 ステージ メソッドの実装を削除する必要があります。
二段回転アニメーションを使ってないから不思議!ソース コードのどこにもSecondHalfメソッドのバリアントはありません。
悲しいかな、私の回転認識 VC は、回転が発生していることを通知されません (回転が画面上で発生したとしても)。騒乱と悲しみが続く。:(
この時点では、スタックをポップする必要さえありません。
View Controller doc が考えられる問題を示唆していると思います:
向きの変更中にカスタム アニメーションを実行する場合は、2 つの方法のいずれかで実行できます。向きの変更は、回転の開始点、中間点、および終了点で通知が発生する 2 つのステップで発生していました。ただし、iPhone OS 3.0 では、方向の変更を 1 ステップで実行するためのサポートが追加されました。1 ステップの方向変更を使用すると、古い 2 ステップのプロセスよりも高速になる傾向があり、通常、新しいコードには推奨されます。
MoreNavigationControllerはまだ 2 段階のプロセスに応答しているので、1 段階のプロセスを使用しようとする試みがうまくいかないのだろうか? 2 段階のメッセージに応答すると、1 段階のバリアントは機能しないことに注意してください (ドキュメントによると)。私は彼らに返信していませんが、IS の背後に何かがあるのではないかと密かに疑っています。
実際、シングルステップ メソッドをコメント アウトして、willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:に応答しようとすると、メモが表示されます。しかし、それはまだ (ビジュアルの点で) きれいにスタックから飛び出すわけではありません。さらに奇妙な: shouldAutorotateToInterfaceOrientation:で (FirstHalf メッセージを使用して) 自分自身への呼び出しをこっそり実行しようとした場合でも、 willAnimateFirstHalfOfRotationFromInterfaceOrientation:duration: は呼び出されません。まるで私がそれを定義したことがないかのように、トレース中にすぐに戻ります。はぁ。
それが実況です。
要約すると、Tab Bar Controller のMoreNavigationController内から呼び出された VC のワンステップ デバイス ローテーションを正常に処理した人はいますか? 探究心が知りたい!