web-dev-qa-db-ja.com

iOS 8でView Controllerの向きを強制するにはどうすればいいですか?

IOS 8より前では、supportedInterfaceOrientationsおよびshouldAutoRotateと共に、以下のコードを使用しました。アプリの向きを特定の向きに強制するためのメソッドを委任します。以下のコードスニペットを使用して、プログラムでアプリケーションを目的の向きに回転させました。まず、ステータスバーの向きを変えています。次に、モーダルビューを表示してすぐに閉じると、ビューが目的の向きに回転します。

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

しかし、これはiOS 8では失敗しています。また、私は、iOS 8以降では常にこのアプローチを避けるべきであると人々が示唆したところで、スタックオーバーフローにおいていくつかの答えを見ました。

より具体的に言うと、私のアプリケーションはユニバーサルタイプのアプリケーションです。合計3つのコントローラーがあります。

  1. First Viewコントローラ - iPadではすべての向きをサポートし、iPhoneでは縦向き(ホームボタンダウン)のみをサポートします。

  2. セカンドビューコントローラー - あらゆる状況において、風景のみをサポートします。

  3. Third Viewコントローラ - それはあらゆる状況で正しい風景だけをサポートするべきです

ページナビゲーションにNavigation Controllerを使用しています。最初のView Controllerから、ボタンクリックアクションで、スタック上の2番目のものを押しています。そのため、2台目のView Controllerが到着したときは、デバイスの向きに関係なく、アプリは横向きでのみロックされます。

以下は、2番目と3番目のView ControllerのshouldAutorotateメソッドとsupportedInterfaceOrientationsメソッドです。

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

IOS 8用に特定の向きでView Controllerをロックするための、この方法またはそれ以上の方法で解決策はありますか。

142

IOS 7 - 10の場合:

目的C:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

スイフト3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

表示されているView Controllerの- viewDidAppear:で呼び出すだけです。

298
Sunny Shah

あなたがUINavigationControllerまたはUITabBarControllerの中にいるならば、方位回転はもう少し複雑です。問題は、これらのコントローラの1つにView Controllerが組み込まれている場合、Navigation ControllerまたはTab Bar Controllerが優先され、自動回転とサポートされている方向が決定されることです。

UINavigationControllerとUITabBarControllerに次の2つの拡張機能を使用して、これらのコントローラーの1つに埋め込まれているビューコントローラーが決定を下すようにします。

ビューコントローラに力を与える!

Swift 2.3

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

スイフト3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

これでsupportedInterfaceOrientationsメソッドをオーバーライドできます。ロックしたいビューコントローラでshouldAutoRotateをオーバーライドできます。それ以外の場合は、アプリケーションのplistで指定されているデフォルトの向きの動作を継承する他のView Controllerでオーバーライドを除外できます。

回転を無効にする

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

特定の方向に固定

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

理論的には、これはすべての複雑なView Controller階層に対して機能するはずですが、UITabBarControllerに問題があることに気付きました。何らかの理由で、デフォルトの方向値を使用したいのです。問題のいくつかを回避する方法について知りたい場合は、次のブログ投稿を参照してください。

画面の回転をロックする

91
Korey Hinton

これは私のために働いたものです:

https://developer.Apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//Apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

あなたのviewDidAppear:メソッドでそれを呼び出します。

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIViewController attemptRotationToDeviceOrientation];
}
23
Vincil Bishop

表示されているView Controllerの場合は、preferredInterfaceOrientationForPresentationをオーバーライドできることがわかりました

迅速:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}
20
Zipme

この方法はSwift 2 iOS 8.xで私のために働きます:

PS(このメソッドはすべてのviewControllerでshouldautorotateのような方向関数をオーバーライドする必要はありません。AppDelegateでは1つのメソッドのみ)

あなたのプロジェクトの一般的な情報で「全画面が必要」をチェックしてください。 enter image description here

そこで、AppDelegate.Swift上で変数を作成します。

var enableAllOrientation = false

だから、また、この関数を置く:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

したがって、プロジェクト内のすべてのクラスで、この変数をviewWillAppearに設定できます。

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

デバイスの種類に基づいて選択する必要がある場合は、次のようにします。

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }
15

まず第一に - これは悪い考えです、一般的に、あなたのアプリのアーキテクチャではうまくいかないことですが、そうであれば、sh..t happens、あなたは以下のようなことを試みることができます:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

        UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
    }
}

AppDelegateより

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return OrientationController.allowedOrientation
}

そして向きを変えたいときはいつでも:

OrientationController.forceLockOrientation(.landscapeRight)

注:時々、デバイスはそのようなコールからアップデートしないかもしれません、従って次のようにする必要があるかもしれません

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

それで全部です

10
gbk

これはiOS 6以降で動作するはずですが、私はiOS 8でのみテストしました。サブクラスUINavigationControllerをサブクラス化して次のメソッドをオーバーライドします。

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

または可視のView Controllerに依頼する

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

- (BOOL)shouldAutorotate {
    return self.visibleViewController.shouldAutorotate;
}

そしてそこにメソッドを実装します。

9
Mojo66

これは、 Sid Shahの答え のコメントへのフィードバックです。

[UIView setAnimationsEnabled:enabled];

コード:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}
9
ohho

Xcode 8では、メソッドはプロパティに変換されるので、以下はSwiftに対して機能します。

override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}
6
Ali Momen Sani

NavigationViewControllerを使用している場合は、このために独自のスーパークラスを作成して、それをオーバーライドする必要があります。

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

これはSecondViewControllerの回転を無効にしますが、デバイスが縦向きのときにSecondViewControllerを押すと、SecondViewControllerはポートレートモードで表示されます。

ストーリーボードを使用しているとします。手動セグエ( How to )を作成し、 "onClick"メソッドで作成する必要があります。

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

これにより、スーパークラスが自動回転機能を無効にする前に、横向きになります。

6
Lau

私は多くの解決策を試してみましたが、うまくいったのは以下のとおりです。

Ios 8と9ではinfo.plistを編集する必要はありません。

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Appleのドキュメント から考えられる向き:

UIInterfaceOrientationUnknown

装置の向きは判別できません。

UIInterfaceOrientationPortrait

デバイスは縦置きで、ホームボタンは下部にあります。

UIInterfaceOrientationPortraitUpsideDown

デバイスは縦向きになっていますが、上下逆さまになっています。ホームボタンは上部にあります。

UIInterfaceOrientationLandscapeLeft

デバイスは横向きになっています。デバイスは垂直に、ホームボタンは左側にあります。

UIInterfaceOrientationLandscapeRight

デバイスは横向きになっており、デバイスは縦に持ち、ホームボタンは右側にあります。

4
hoogw

SidsとKoreysの答えを組み合わせて私のために働いた。

Navigation Controllerを拡張する

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

それから、単一のビューで回転を無効にします

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

そしてセグエの前に適切な向きに回転させる

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}
3
Misha

[iOS9 +]上記の解決策がうまくいかず、だれかがここまでずっと下にドラッグした場合や、ビューを提示して向きを変えたい場合は、これを確認することをお勧めします。

あなたのセグエのプレゼンテーションの種類を確認してください。私のものは「現在の状況を超えて」いました。フルスクリーンに変更したときは、うまくいきました。

@GabLeRouxのおかげで、私はこの解決策を見つけました。

  • この変更は、上記の解決策と組み合わせた場合にのみ機能します。
2
Goh

私の要求は

  1. すべてのビューを縦向きモードでロックします
  2. AVPlayerViewControllerを使ってビデオを再生する

ビデオが再生されているときに、それが横長であれば、画面を横長にし、横長にすることができます。ポートレートの場合は、ビューをポートレートモードでのみロックします。

まず、AppDelegate.SwiftsupportedInterfaceOrientationsForWindowを定義します。

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

次に、メインのView Controllerで、以下の機能を定義します。

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func shouldAutorotate() -> Bool {
    return false
}

次に、AVPlayerViewControllerをサブクラス化する必要があります

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

MyPlayerViewController.Swiftでこれら3つの関数をオーバーライドします

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

ユーザーはデバイスを左または横に回転させる可能性があるため、自動回転をtrueに設定する必要があります。

override func shouldAutorotate() -> Bool {
    return true
}

最後に、View ControllerにMyPlayerViewControllerインスタンスを作成し、プロパティサイズの値を設定します。

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

プレイヤーを適切なvideoUrlで開始してから、プレイヤーをplayerViewControllerに割り当てます。ハッピーコーディング!

2
charles.cc.hsu

上記のトップソリューション:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

表示されているView ControllerのviewDidAppearで呼び出したとき、うまくいきませんでした。しかし、表示側のView ControllerのpreparForSegueで呼び出したときはうまくいきました。

(申し訳ありませんが、このソリューションについてコメントするには評判が足りないため、このように追加する必要がありました)

2
guido
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}
2

Korey Hintonの答えによると

Swift 2.2:

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return visibleViewController!.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController!.shouldAutorotate()
    }
}


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

回転を無効にする

override func shouldAutorotate() -> Bool {
    return false
}

特定の方向に固定する

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}
1
phnmnn

ここでいくつか解決策を試しましたが、理解するべき重要なことは、それが回転するかどうかを決定するのはルートビューコントローラであるということです。

以下のobjective-cプロジェクト github.com/GabLeRoux/RotationLockInTabbedViewChild を実用例で作成しました。一方の子ビューは回転を許可され、もう一方の子ビューは縦長にロックされているTabbedViewController

それは完璧ではありませんが、それはうまくいき、NavigationViewControllerのような他の種類のルートビューにも同じ考えがうまくいくはずです。 :)

Child view locks parent orientation

1
GabLeRoux

このタスクを達成するための最善の方法についてはまだいくつか議論があるように思われるので、私は自分の(作業中の)アプローチを共有したいと思いました。 UIViewController実装に次のコードを追加します。

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

この例では、プロジェクト設定で(または直接info.plistで)許可されているデバイスの向きを 'Landscape Left'に設定する必要もあります。 LandscapeLeft.以外のものが必要な場合は、強制したい特定の方向を変更するだけです。

私にとって重要なことは、attemptRotationToDeviceOrientation内のviewWillAppear呼び出しでした。それがなければ、デバイスを物理的に回転させないとビューは正しく回転しません。

0
ViperMav

私は同じ問題を抱えており、そのために多くの時間を無駄にしています。だから今、私は私の解決策を持っています。私のアプリの設定はポートレートのみをサポートしていますが、アプリの一部の画面には横向きのみが必要です。変数isShouldRotate at AppDelegateを使用して修正します。そして、AppDelegateの関数:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

そして最後にViewControllerAがランドスケープ状態を必要とするとき。 Push/present to ViewControllerA assign isShouldRotateの前に= to true。そのコントローラーがisShouldRotatefalseviewWillDisappearに割り当てる場合は、忘れないでください。

0
lee

@ sid-shaによって示された解決策によれば、あなたはすべてをviewDidAppear:メソッドに入れなければなりません、さもなければ、あなたはdidRotateFromInterfaceOrientation:を起動させないでしょう。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}
0
loretoparisi

ここにいるあなたでさえ、私には誰もが足りないほど多くの答えがあるようです。私は強制的に向きを決めた後、戻ってデバイスの向きに戻りたいのですが、[UIViewController attemptRotationToDeviceOrientation];はうまくいきませんでした。また、全体的に複雑なことは、ある回答に基づいてshouldAutorotateをfalseに追加したため、すべてのシナリオで正しい効果が得られないことです。

だからこれは私がやったことです:

彼のinitコンストラクタでコントローラを呼び出す前に、次のようにします。

_userOrientation = UIDevice.currentDevice.orientation;
[UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
[self addNotificationCenterObserver:@selector(rotated:)
                               name:UIDeviceOrientationDidChangeNotification];

だから私は最後のデバイスの向きを保存し、向きの変更イベントに登録します。向き変更イベントは簡単です。

- (void)rotated:(NSNotification*)notification {
    _userOrientation = UIDevice.currentDevice.orientation;
}

そして、見方を棄却して、私はuserOreintationとして私が持っているどんなオリエンテーションにもただ強制的に戻します

- (void)onViewDismissing {
    super.onViewDismissing;
    [UIDevice.currentDevice setValue:@(_userOrientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

そしてこれもまた存在しなければならない:

- (BOOL)shouldAutorotate {
    return true;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

また、ナビゲーションコントローラはshouldAutorotateとsupportedInterfaceOrientationsに委任する必要がありますが、ほとんどの人がすでに持っていると思います。

PS:すみません、私はいくつかの拡張と基本クラスを使います、しかし名前はかなり意味があるので概念は理解できます、それは今あまりきれいではないのでもっと多くの拡張を作るでしょう。

0
Renetik

私の解決策

AppDelegate内:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewControllerは、ランドスケープモードをサポートしたいViewControllerです。

それなら Sunny Shahのソリューション はあなたのXXViewControllerでどんなiOSバージョンでもうまくいくでしょう:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

これは、最上位のViewControllerを見つけるためのユーティリティ関数です。

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}
0
duan

私にとっては、最上位のVCは、向きの上書きを実装する必要がありました。先頭のVCが実装されていない場合、スタックの下にVCを使用しても効果はありません。

VC-main
    |
    -> VC 2
        |
        -> VC 3

基本的に私のテストでは、VC-Mainだけが聴かれています。

0
bduhbya

これを使用して、IOS 9でテストされたView Controllerの向きを固定します。

//向きを横向きに固定

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}
0
robegamesios