Root ViewController と Orientation の関係

複数のViewController を作成し、それぞれ shouldAutorotate, supportedInterfaceOrientations を設定しても、ルートViewControllerしかその設定が反映されない。何故だろうと思い、調べたところ、ViewControllerはルートViewControllerとそれ以外の ViewController で動きが違うことがわかった。詳細は、次のURLを参照。

iOS 8以降、回転はViewController の View のサイズを変更することで対応するようになった。インターフェースの向きが変わると、UIKitはウィンドウのルートViewController で viewWillTransitionToSize メソッドを呼び出します。次に、そのViewController は子ビューコントローラーに通知し、メッセージをビューコントローラー階層全体に伝達します。 したがって、ルートViewController のshouldAutorotate, supportedInterfaceOrientationsは参照されるが、子のViewControllerでは、これらの値は参照されない。したがって、子のViewControllerの shouldAutorotate, supportedInterfaceOrientations を設定しても、orientationを制約することができない。viewWillTransitionToSize から回転を設定するのが正しいアプローチ思われる。

無理やり変更するのであれば、子のViewController が表示されていても、ルートViewController の shouldAutorotate, supportedInterfaceOrientations が呼び出されるので、その時に表示されている presentedViewControllerの設定値を返すようにする。

import UIKit


class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        print("MenuViewController viewDidLoad")
    }


    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let vc = presentedViewController {
            print("ViewController supportedInterfaceOrientations for Menu")
            return vc.supportedInterfaceOrientations
        } else {
            print("ViewController supportedInterfaceOrientation for Main")
            return [.portrait, .landscapeRight]
        }
    }
    
    override var shouldAutorotate: Bool {
        if let vc = presentedViewController {
            print("ViewController shouldAutorotate for Menu")
            return vc.shouldAutorotate
        } else {
            return true
        }
    }
    
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        print("ViewController preferredInterfaceOrientationForPresentation")
        return UIInterfaceOrientation.portrait
    }
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        
        print("Main viewWillTransition")
                
    }
}

投稿者: admin

Free Software Engineer

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です