web-dev-qa-db-ja.com

iOS6:supportedInterfaceOrientationsが機能しません(呼び出されますが、インターフェースは引き続き回転します)

私のアプリには複数のビューがあり、一部のビューはポートレートとランドスケープの両方をサポートする必要がありますが、他のビューはポートレートのみをサポートする必要があります。したがって、プロジェクトの概要では、すべての方向をすべて選択しました。

以下のコードは、iOS 6より前の特定のView Controllerで横向きモードを無効にするために機能しました。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

ShouldAutorotateToInterfaceOrientationはiOS6で廃止されたため、上記を次のように置き換えました。

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMask.Portrait;
}

ビューが表示されるときにこのメソッドは正しく呼び出されます(ブレークポイントを設定してこれを保証できます)が、ポートレートモードのマスクのみを返すという事実に関係なく、インターフェイスは引き続きランドスケープモードに回転します。私は何を間違えていますか?

現在、ビューごとに異なる向きの要件を持つアプリを構築することは不可能のようです。プロジェクトの概要で指定された方向のみを順守しているようです。

50
aneuryzm

INavigationControllerをルートウィンドウコントローラーとしてを使用している場合、itsshouldAutorotatesupportedInterfaceOrientationsが呼び出されます。

ITabBarControllerなどを使用しているかどうかを確認します。

そのため、すべきことは、Navigation/Tabbar Controllerをサブクラス化し、そのshouldAutorotatesupportedInterfaceOrientationsメソッドをオーバーライドすることです。

69
Martin

appDelegate.mでこのコードを変更してみてください

//   self.window.rootViewController = self.navigationController;

    [window setRootViewController:navigationController];

これは完全な答えです

iOS 6ではshouldAutorotateToInterfaceOrientationが呼び出されない

XD

30
NSStudent

私の場合、UINavigationControllerとView Controllerが内部にあります。 UINavigationControllerをサブクラス化する必要があり、Portraitのみをサポートするには、このメソッドを追加します。

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

そのため、UINavigationControllerサブクラスでは、現在のtopViewControllerでサポートされている方向を確認する必要があります。

- (NSUInteger)supportedInterfaceOrientations
{
    return [[self topViewController] supportedInterfaceOrientations];
}
20
Pavel

私が見つけた1つのことは、あなたがまだしている古いアプリケーションを持っているかどうかです

[window addSubView:viewcontroller.view];  //This is bad in so may ways but I see it all the time...

次のように更新する必要があります。

[window setRootViewController:viewcontroller]; //since iOS 4

これを行うと、オリエンテーションが再び機能し始めます。

15
James Jones

IOS6の最適な方法は、レイウェンダリッヒチームによる「チュートリアルによるiOS6」に具体的に記載されています- http://www.raywenderlich.com/ ほとんどの場合、UINavigationControllerをサブクラス化するよりも優れています。

IOS6を使用して、初期ビューコントローラーとして設定されたUINavigationControllerを含むストーリーボードを使用しています。

//AppDelegate.m-このメソッドは、残念ながらiOS6以前では使用できません

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m-各UIViewControllerでサポートする向きを返します

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}
14
Phil

他の人が述べたように、UINavigationControllerを使用していて、さまざまなビューをカスタマイズする場合、UINavigationControllerをサブクラス化し、これらの2つのコンポーネントがあることを確認します。

@implementation CustomNavigationController

// -------------------------------------------------------------------------------
//  supportedInterfaceOrientations:
//  Overridden to return the supportedInterfaceOrientations of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations]; 
}

// -------------------------------------------------------------------------------
//  shouldAutorotate
//  Overridden to return the shouldAutorotate value of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  YES when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (BOOL)shouldAutorotate
{
    return [self.topViewController shouldAutorotate];
}

次に、ポートレートのみのビューに次のものを含めます。

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

そして、すべてのビューで、逆さまを除いてすべてです:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}
10
Causaelity

基本的に上記の誰かが述べたように、しかしより詳細に:

  1. UINavigationControllerのサブクラスである新しいファイルを作成します
  2. ストーリーボードに移動し、Navigation Controllerをクリックして、作成したクラスにクラスを設定します
  3. このクラス(.mファイル)に次のコードを追加して、ポートレートモードのままにします。

    (BOOL)shouldAutorotate
    {
      return NO;
    } 
    
    (NSUInteger)supportedInterfaceOrientations
    {
     return UIInterfaceOrientationMaskPortrait;
    }
    

これは私のために働いた

2
user1601259

UINavigationControllerUITabbarControllerをサブクラス化するのではなく、カテゴリを作成するのが最善の方法だと思います

uINavigationController + Rotation.h

#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation)

@end

uINavigationController + Rotation.m

#import "UINavigationController+Rotation.h"

@implementation UINavigationController (Rotation)

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

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

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}


@end

すべてのコントローラーにこのカテゴリーをインポートさせ、これが魅力のように機能するようにしてください。コントローラーを回転させずに、回転する別のコントローラーを押すこともできます。

1
Vassily

このコードは私のために働いた:

-(BOOL)shouldAutorotate {
     return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

iPhone/iPadアプリの向き 自分の答えを確認する

1
tcd

UITabBarController内でUINavigationControllersを使用しているため、切り取りと貼り付けだけでは機能しませんでしたが、ここでの回答は正しい方向を示しています。したがって、AppDelegate.mの私のバージョンはこのようなもので、UITabBarController内のUITabBarControllers、UINavigationControllers、またはUINavigationControllersで機能します。他のカスタムコンテインメントコントローラーを使用している場合は、ここに追加する必要があります(これはちょっと残念です)。

- (UIViewController*)terminalViewController:(UIViewController*)viewController
{
  if ([viewController isKindOfClass:[UITabBarController class]])
  {
    viewController = [(UITabBarController*)viewController selectedViewController];
    viewController = [self terminalViewController:viewController];
  }
  else if ([viewController isKindOfClass:[UINavigationController class]])
  {
    viewController = [[(UINavigationController*)viewController viewControllers] lastObject];
  }

  return viewController;
}

- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
  UIViewController* viewController = [self terminalViewController:window.rootViewController];

  if (viewController)
    orientations = [viewController supportedInterfaceOrientations];

  return orientations;
}

注意すべきもう1つの重要な点は、UIViewControllerサブクラスでsupportedInterfaceOrientationsをオーバーライドする必要があることです。そうしないと、Info.plistで指定したものがデフォルトになります。

0
Ray Fix

UINavigationControllerを使用している場合、shouldAutorotateのサブクラスにsupportedInterfaceOrientationsおよびUINavigationControllerを実装する必要があります。

これらは2つのステップで制御できます。shouldAutorotateがYESを返し、その後supportedInterfaceOrientationsを返します。とてもいい組み合わせです。

この例では、CoverFlowViewとPreviewViewを除くほとんどのビューはPortraitです。 CoverFlowViewはPreviewViewに転送されます。PreviewViewはCoverFlowCViewの回転を追跡します。

@implementation MyNavigationController

-(BOOL)shouldAutorotate
{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")])

return NO;

else

return YES;

}



-(NSUInteger)supportedInterfaceOrientations

{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")])

return UIInterfaceOrientationMaskAllButUpsideDown;

else

return UIInterfaceOrientationMaskPortrait;

}

...

@end
0
Y.Muranaka

私のソリューション:UINavigationControllerをサブクラス化し、window.rootViewControllerとして設定します

階層の最上位のビューコントローラーが方向を制御します。いくつかのコード例: subclassed UINavigationController

0
Carina

shouldAutorotateメソッドを追加してみてください

0
Kubba

あなたと同じ状況です。あなたはすでに答えを受け入れましたが、とにかく別の答えを追加すると思いました。これが、回転システムの新しいバージョンが機能することを理解する方法です。ルートView Controllerは、呼び出される唯一のView Controllerです。理由は、子View Controllerではビューを回転させることはあまり意味がないことだと思う、とにかくルートView Controllerのフレーム内にとどまるからだ。

それで、何が起こるか。最初にshouldAutorotateが呼び出されますルートView Controller上NOが返された場合、すべてが停止します。 YESが返された場合、supportedInterfaceOrientationsメソッドが呼び出されます。このメソッドおよびでInfo.plistまたはアプリケーションデリゲートからサポートされているグローバルな向きでインターフェイスの向きが確認されると、ビューが回転します。回転の前に、shouldAutomaticallyForwardRotationMethodsメソッドが照会されます。 YES(デフォルト)の場合、すべての子はwillおよびdidRotateTo...メソッドと親(そしてそれらは順番に子に転送します)。

私の解決策(より雄弁なものがあるまで)は、supportedInterfaceOrientationsメソッドの間に最後の子View Controllerを照会し、その値を返すことです。これにより、一部の領域を回転させながら、他の領域をポートレートのみに維持できます。私はそれが壊れやすいことを理解していますが、イベント呼び出しやコールバックなどで物事を複雑にすることを伴わない別の方法は見当たりません。

0
borrrden

まず、アプリをオンリーモードで動作させるには、UIInterfaceOrientationMaskLandscapeを返す必要があります。ポートレートモードのみを維持したい場合は、正しく処理しています。

Info.plistにUISupportedInterfaceOrientationsキーを追加し、アプリが保持する予定のインターフェイスの向きの値を割り当てます。

また、自動回転を完全に回避したい場合は、shouldAutoRotateからfalseを返す必要があります。ただし、ここからtrueを返し、supportedInterfaceOrientationsメソッドで正しい方向を指定することをお勧めします。

0
Varun Bhatia