web-dev-qa-db-ja.com

iOS 6の自動回転には奇妙な動作があります

ビデオを再生し、他のUITabBarControllerタブに他の情報を表示するUITabBarアプリがあります。 iOS 6では、UIView回転メソッドは非推奨になりました。現在、shouldAutoRotateおよびsupportedInterfaceOrientationsメソッドを使用する必要があります。ビデオの再生には、MPMoviePlayerViewControllerを使用します。

このプレーヤービューのみを回転させる方法は?アプリ全体を回転させることしかできませんが、これを行いたくありません。 MPMoviePlayerViewControllerを提示しますが、iOS 5以前のように回転しません。

plist設定では、ポートレートインターフェイスの方向を1つだけ設定しました。他を設定すると、アプリ全体が回転します。

28
Timur Mustafaev

AppleのiOS 6 SDKリリースノートから:

IOS 6では自動回転が変更されています。iOS6では、UIViewControllerのshouldAutorotateToInterfaceOrientation:メソッドは非推奨になりました。その代わりに、supportedInterfaceOrientationsForWindow:およびshouldAutorotateメソッドを使用する必要があります。

より多くの責任がアプリとアプリの委任に移っています。現在、iOSコンテナ(UINavigationControllerなど)は、自動回転する必要があるかどうかを判断するために子を参照しません。 デフォルトでは、アプリとView Controllerのサポートされるインターフェイスの向きは、iPadイディオムのUIInterfaceOrientationMaskAllとiPhoneイディオムのUIInterfaceOrientationMaskAllButUpsideDownに設定されます。

View Controllerでサポートされているインターフェイスの向きは時間とともに変化する可能性があります。アプリでサポートされているインターフェイスの向きも時間とともに変化する可能性があります。 システムは、デバイスが回転するとき、またはビューコントローラーにフルスクリーンモーダルが表示されるたびに、サポートされているインターフェイスの向きを最上部のフルスクリーンビューコントローラー(通常はルートビューコントローラー)に要求しますプレゼンテーションスタイル。さらに、このView ControllerがshouldAutorotateメソッドからYESを返す場合にのみ、サポートされている方向が取得されます。 システムは、View Controllerのサポートされている向きとアプリのサポートされている向き(Info.plistファイルまたはアプリデリゲートのapplication:supportedInterfaceOrientationsForWindow:メソッドによって決定される)と交差して、回転するかどうかを決定します

システムは、アプリのsupportedInterfaceOrientationsForWindow:メソッドによって返される値と、最上部のフルスクリーンコントローラーのsupportedInterfaceOrientationsメソッドによって返される値を交差させることにより、方向がサポートされているかどうかを判断します。 setStatusBarOrientation:animated:メソッドは完全に非推奨ではありません。これは、最上部のフルスクリーンビューコントローラーのsupportedInterfaceOrientationsメソッドが0を返す場合にのみ機能するようになりました。これにより、呼び出し側は、ステータスバーの方向が一貫していることを確認する責任があります。

互換性のために、shouldAutorotateToInterfaceOrientation:メソッドをまだ実装しているView Controllerは、新しい自動回転動作を取得しません。 (つまり、アプリ、アプリデリゲート、またはInfo.plistファイルを使用して、サポートされている向きを決定することはありません。)代わりに、shouldAutorotateToInterfaceOrientation:メソッドを使用して、supportedInterfaceOrientationsメソッドによって返される情報を合成します。 。

アプリ全体を回転させる場合は、Info.plistを設定してすべての方向をサポートする必要があります。特定のビューをポートレートのみにしたい場合は、何らかのサブクラスを実行し、オートローテーションメソッドをオーバーライドしてポートレートのみを返す必要があります。ここに例を示します:

https://stackoverflow.com/a/12522119/1575017

45
rocky

おお!半日が費やされ、問題は解決しました!彼彼。

上記のドキュメントにあるように、これは本当にそれです!コアポイントは次のとおりです。

詳細責任はアプリとアプリのデリゲートに移っています。現在、iOSコンテナ(UINavigationControllerなど)は、自動回転する必要があるかどうかを判断するために子を参照しません。デフォルトでは、アプリとView Controllerのサポートされるインターフェイスの向きは、iPadイディオムではUIInterfaceOrientationMaskAllに、iPhoneイディオムではUIInterfaceOrientationMaskAllButUpsideDownに設定されます。

そのため、ルートコントローラーのあるものが変更されるたびに、システムはアプリのデリゲートに「だから、私たちは何ですか?回転するのかどうか」を尋ねます。

「回転」する場合:

サポートされている向きは、このView ControllerがshouldAutorotateメソッドからYESを返した場合にのみ取得されます

システムはアプリのデリゲートを要求します

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {    

    return ...;
}

それは本当に簡単です。

ポートレートやランドスケープなどをいつ許可するかを決定する方法は、あなた次第です。ルートコントローラーのテストはいくつかの点で私にとっては機能しませんでしたが、これは機能します。

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {    

    return self.fullScreenVideoIsPlaying ?
        UIInterfaceOrientationMaskAllButUpsideDown :
        UIInterfaceOrientationMaskPortrait;
}

プロパティ「fullScreenVideoIsPlaying」は、必要なときにいつでも手動で設定されます。

注意すべき他の唯一の重要なことは列挙型です。ドキュメントにあるように...(iPad/iPhoneのことを注意深く読んでください)。だから、あなたは必要に応じてそれらと遊ぶことができます。

もう1つの小さなことは、プレーヤーコントローラーを閉じた後のバグのある動作です。オリエンテーションを変更しなかったことが一度ありましたが、それは一度だけ、奇妙な方法で、シミュレーターでのみ起こりました(もちろんiOS 6のみ)。そのため、予期せぬ事態が発生し、アプリの他の要素をすばやくクリックした後、通常の方向に回転したため、反応さえできませんでした。それで、確かではありません-シミュレーターの動作の遅延または何かかもしれません(または、実際にはバグ:).

幸運を!

13
Agat

アプリでも同じ問題が発生しました。

IOS 6での回転の仕組みはそれです。

=> UINavigationCOntrollerを使用しているときはAppDelegateのメソッド

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window    
{
   return 
}

回転するかどうかを決定します。

=>ビューがモーダルプレゼンテーションスタイルで表示される場合、メソッド

- (BOOL)shouldAutorotate

そのビューのviewController内にあるappDelegateのメソッドをトリガーします。そして、最初のケースとして、appDelegateは回転するかどうかを決定します。

私の解決策::

モーダルプレゼンテーションのために私がしたことはそれでした。アプリデリゲートでフラグを作成しました。

フラグがYESの場合、横向きに回転し、そうでない場合は唯一の縦向きになります。

- (NSUInteger)application:(UIApplication*)application
supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
    if(self.shouldRotate ) //shouldRotate is my flag
    {
        self.shouldRotate = NO;
        return (UIInterfaceOrientationMaskAll);
    }
    return (UIInterfaceOrientationMaskPortrait);
}

そして、回転を切り替えるには

- (BOOL)shouldAutorotate
{
    YourAppDelegate *mainDelegate = (YourAppDelegate*)[[UIApplication sharedApplication]delegate];
    mainDelegate.shouldRotate = YES;

    return YES;
}

:これは、Modely Presentedのビューにのみ有効です。 Flagを使用することは、良いコーディング手法ではありません。

7
Vipin Johney

UITabBarControllerをサブクラス化して、次のようにshouldAutorotateおよびsupportedInterfaceOrientationについて子に問い合わせることもできます。

@implementation MyTabBarController

-(BOOL)shouldAutorotate
{
    return [self.selectedViewController shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [self.selectedViewController supportedInterfaceOrientations];
}

@end

次に、標準のコンテナの代わりにカスタムコンテナを使用するだけで機能します。ただテストした。

3
Serge Kutny

残念ながら、plistですべての方向をオンにし、回転させたくないすべてのView ControllerでsupportedInterfaceOrientationsを使用する必要があります。 (あなたの場合、ビデオプレーヤー以外はすべて。)

2
Anthony

これを試して、

TabBarControllerがウィンドウのRootViewControllerである場合、TabBarControllerを継承するカスタムクラスを作成すると、CustomTabBarController.hと言います。

CustomTabBarController.hに以下のメソッドを追加します

-(NSUInteger)supportedInterfaceOrientations // Must return Orientation Mask

最後にAppDelegate.mで以下を呼び出します

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window  {
   if( [self.window.rootViewController supportedInterfaceOrientations]!=0) 
     {
        return [self.window.rootViewController supportedInterfaceOrientations];
    }
    return UIInterfaceOrientationMaskAll;
}
1
Vinay

これを設定する最も簡単な方法は、[サポートされているインターフェイスの向き]ボタンを使用することです。[ターゲット] ... [概要]タブ(iPhone/iPadの展開情報)を見ると確認できます。

基本的にplistファイルを設定するためのGUI

0
Tim