質問

アップデート:まずはこの質問に対する私の回答をご覧ください。これはバグのようです。最小限のテスト ケースが作成され、レポートが Apple に提出されました。(iPhone OS 3.1では修正されています。)

これが「私はとても近い!」のパズルです。部門。

タブバーベースの iPhone アプリがあります。各タブの機能は、 UINavigationController 通常の容疑者(ナビゲーションバー、テーブルビュー...それが別の VC などにつながる可能性があります)。

ここで、それらの下位レベルの VC の 1 つがポートレートで使用されます。 そして 風景モード。しかし、問題があります。景観に配慮した当社の VC shouldAutorotateToInterfaceOrientation: すぐに呼ばれることはありません!何をするか?

これが私たちのやることです。独自のファイルに実装したタブ バー コントローラーには、次のようになります。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
     return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

これにより、最終的に私のランドスケープフレンドリーな VC にリクエストが伝播され、VC もこのメッセージに応答します。私の他のすべての VC はこのメソッドを実装していないため、単純にデフォルトの縦向きを使用します。

問題が解決しました!!!わーい!

良い、 完全ではありません。 :(

ランドスケープフレンドリーな VC がタブ バー コントローラーの奥から呼び出されると、物事があまりうまくいかないようです。 詳細ナビゲーションコントローラー.

私は、いずれかの内部から呼び出された VC を比較/対照することにしました。 最初の4つ タブバー UINavigationController ...そしてその同じ VC が内部から呼び出しました。 詳細ナビゲーションコントローラー. 。これは少し詳細になりますので、ご了承ください。このプレイバイプレイが物事を解明するのに役立つことを願っています。

アプリが読み込まれるとき、タブ バー コントローラーの shouldAutorotate... への最初の呼び出しがいくつかあります。方法。このような初期のケースでは、 選択されたビューコントローラー ゼロです。ただし、最終的には読み込みが完了し、最初のタブ項目が選択され、すべてがうまくいきます。

右。まず、最初の 4 つのタブ バー項目の 1 つを選択し、VC にドリルダウンしましょう。

3 番目のナビゲーション バー項目を選択します。つまり、それが 3 番目のナビゲーション コントローラーになります。ローテーションをサポートする VC までドリルダウンします。簡単に調べてみると、親が確かにタブ バーのビュー コントローラー リストの 3 番目のナビゲーション コントローラーであることが確認できます。良い!

デバイスを回転させてみましょう。タブ バー コントローラーは自動回転するように求められます (上記のコードを参照)。私たちはそれを観察します 選択されたビューコントローラー これは 3 番目のナビゲーション コントローラーでもあり、さらに、ナビゲーション コントローラーの上部と表示されているビュー コントローラーは両方とも、回転をサポートする信頼できる VC に設定されています。

したがって、タブ バー コントローラーは、 自動回転する必要があります メッセージを 3 番目のナビ コントローラーに送信します ...しかし、私たちのローテーションに優しいVCが最終的にメッセージを受け取ります。(ここでは特別なことは何もしていません。おそらく、目的の VC がメッセージを受け取るのは、それが最上位および/または表示されている VC であるためです?) いずれにせよ、横向きに回転し、サイズが変更され、すべてがうまくいきました。"大成功!"

次に、戻るボタンを押して VC スタックをポップし、ランドスケープ モードをそのままにしておきます。タブ バー コントローラーが再度クエリされます。

ここで少し余談の時間です。の トップビューコントローラー 私たちのナビコントローラーはまだ回転に優しいVCですが、 可視ビューコントローラ 現在はに設定されています UIスナップショットモーダルビューコントローラー!へー。これまで見たことがありません...しかし エリカ・サドゥンは. 。これは「ビュー コントローラーが消える」ためのもののようです (この場合は確かに当てはまります。問題なく消えています)。

ステップ実行を続けると、表示されている VC はスナップショットのままですが、特別な VC が最終的になくなるため、最上位の VC は最終的にスタック上の次の VC に変わります。けっこうだ。

それで それは すべてがうまくいくシナリオ。

では、同じテストを試してみましょう。今回のみ、 詳細ナビゲーションコントローラー ([その他] タブ バー項目) をクリックして、前と同じ VC クラスにドリルダウンします。私の場合、それはたまたまタブバーコントローラーのVCリストの7番目でした。

回転を意識した VC に入ります...今度は回転するように求められます 直接!タブバーコントローラーは ない 回転する許可を求めました。ふーむ。

親 VC を簡単に確認すると、それが 詳細ナビゲーションコントローラー. 。なるほど、それは理にかなっています。

次に、デバイスを回転してみましょう。 何も呼び出されない. 。どのブレークポイントもヒットしません。私たちのVCにはありません。タブバーコントローラーにはありません。(はぁ?!?!)

ああ、そうだね。スタックをポップし、同じ VC に戻って、もう一度回転してみます。奇妙な。ここで、タブ バー コントローラーで自動回転の許可を求める呼び出しが行われます。ここで、選択したコントローラーは信頼できる Nav コントローラー (#7) ですが、今回は 可視ビューコントローラ そして トップビューコントローラーゼロに設定!

ここから続行すると、デバッガ コンソールに謎のメッセージが表示されます。

2段階の回転アニメーションを使用します。よりスムーズなシングルステージアニメーションを使用するには、このアプリケーションは2段階のメソッドの実装を削除する必要があります。

神秘的だから 2段階回転アニメーションを使用していません!いいえ 後半 メソッドのバリアントがソース コードのどこにでも存在します。

悲しいことに、私の回転認識 VC には回転が発生していることは決して通知されません (画面上で回転が発生する場合でも)。したがって、結果として私の視界はすべて汚れてしまいます。混乱と悲しみが続きます。:(

この時点では、わざわざスタックをポップする必要はありません。

View Controller のドキュメントには、考えられる問題が示唆されていると思います。

オリエンテーションの変更中にカスタムアニメーションを実行したい場合は、2つの方法のいずれかで行うことができます。方向の変更は、2つのステップで発生するために使用され、回転の最初、中央、およびエンドポイントで通知が発生します。ただし、iPhone OS 3.0では、1つのステップで方向変更を実行するためのサポートが追加されました。1段階の方向変更を使用すると、古い2段階のプロセスよりも高速になる傾向があり、一般的に新しいコードに推奨されます。

かしら 詳細ナビゲーションコントローラー は依然として 2 ステップ プロセスに応答しているため、1 ステップ プロセスを使用しようとしてもつまずいてしまうのでしょうか?2 ステップのメッセージに応答する場合、1 ステップのバリアントは機能しないことに注意してください (これもドキュメントによると)。私は彼らに返答していませんが、IS が裏で何かをしているのではないかと密かに疑っています。

実際、シングルステップメソッドをコメントアウトして、次のように応答しようとすると、 willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:, 、 私 する メモを入手してください!しかし、(ビジュアルの点で) スタックからあまりきれいに取り出されるわけではありません。さらに奇妙なのは: willAnimateFirstHalfOfRotationFromInterfaceOrientation:duration: (FirstHalf メッセージを使用して) 自分自身へのこっそり呼び出しを試みても、呼び出されません。 shouldAutorotateToInterfaceOrientation:. 。定義さえしなかったかのように、トレース中にすぐに返されます。はぁ。

というわけで実況です。

要約すると、 誰でも タブ バー コントローラーの MoreNavigationController 内から呼び出された VC のワンステップ デバイス ローテーションが正常に処理されましたか?探究心のある人は知りたい!

役に立ちましたか?

解決

Apple は UITabBarController をサブクラス化しないことを推奨しているため、代わりにカテゴリを使用して自動回転を処理する簡単な方法を見つけました。詳細...のバグは修正されません。ビュー コントローラーですが、これは仕事を完了するためのより Apple フレンドリーな方法だと思います (つまり、サブクラス化が少なくなります)。

アプリケーションのすべてのタブを適切に自動回転させるために、-ShouldAutorotateToInterfaceOrientation を定義しました。私のカスタムビューコントローラー内にありますが、それらはすべて UITabBarController 内の UINavigationControllers 内にあるため、これら 2 つも応答するまでメッセージはチェーンを介して VC に送信されません。そこで、アプリのデリゲートファイルに次の行を追加しました。

MyAppDelegate.h の下部に追加

@interface UITabBarController (MyApp)
@end

@interface UINavigationController (MyApp)
@end

MyAppDelegate.m の下部に追加されました

@implementation UITabBarController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}
@end

@implementation UINavigationController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}
@end

他のヒント

バグがあるようです。再現可能な最小限のテスト ケースを作成し、Apple Bug Reporter 経由で報告しました (レーダーの問題 7139857).

アップデート:この問題は iPhone OS 3.1 では修正されています。

本質的な問題は次のとおりです。

既にナビゲーションコントローラースタックにあるビューコントローラーは受け取らない willAnimateRotationToInterfaceOrientation:期間:メッセージタブバーコントローラーの「より多くのナビゲーションコントローラー」が使用されている場合。

この問題は、 ない この問題は、タブ バー項目ビュー コントローラが基本ビュー コントローラである場合に発生します。ナビゲーションコントローラーである場合のみ、 のみ 「その他」ナビゲーション階層が使用されている場合。

コンソール メッセージ (2 段階回転アニメーションに関する) は、iPhone OS 3.0 では 1 段階が推奨されているにもかかわらず、フレームワーク内の何か (More Navigation Controller?) が依然として 2 段階アニメーションを使用していることを示唆しています。

それで理由が説明できるかもしれない willAnimateRotationToInterfaceOrientation: その特定の場合には呼び出されません。Apple のビュー コントローラーのドキュメントによると、このメッセージは、2 段階の前半/後半の方向メッセージが代わりに応答される場合には呼び出されません。

わずかに修正されたバージョン ヴィクトルブの答え これにより、すべてのビュー コントローラーが回転を許可するかどうかを決定できるようになります。

コピーとフォークを簡単にするための要点としてここにあります

AppDelegate.h

@interface UITabBarController (MyApp)
@end

@interface UINavigationController (MyApp)
@end

AppDelegate.m

@implementation UITabBarController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    UIViewController *selectedVC = [self selectedViewController];
    if ([selectedVC respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
        return [selectedVC shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
    }

    //optimistic return - if you want no rotation, you have to specifically tell me!
    return YES;
}
@end

@implementation UINavigationController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    UIViewController *visibleVC = [self visibleViewController];
    if ([visibleVC respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
        return [visibleVC shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
    }

    //optimistic return - if you want no rotation, you have to specifically tell me!
    return YES;
}
@end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top