Project Unknown's Blog

Peojct.Unknownと言う名前で細々とアプリ開発をやってるメンバーのブログです。

一部のViewControllerだけ端末の回転をさせる方法

ゆう@あんのうんです。

今日のお題は、一部のViewControllerだけ端末の回転をさせる方法です。

注意点

UINavigationControllerにぶら下がっているViewControllerはshouldAutorotate()は呼ばれません。
UINavigationControllerにViewControllerがぶら下がっている場合は、UINavigationControllerのshouldAutorotateが呼ばれてしまう為、ViewController単位で制御できなくなります。 (ぶら下がっていなければ、ViewControllerで呼ばれます。)

やり方紹介にあたっての前提

Projectでの回転の設定は以下に設定しています img

Portrait, LandscapeLeft, LandscapeRightにチェックをいれています。

UINavigationControllerにViewControllerがぶら下がっていない場合

回転させたいViewController

回転のロジックを埋め込んであげます

// ## hogehogeViewController.swift

override func shouldAutorotate() -> Bool {
    return true
}
    
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    let orientation: UIInterfaceOrientationMask = [UIInterfaceOrientationMask.Portrait, UIInterfaceOrientationMask.LandscapeRight, UIInterfaceOrientationMask.LandscapeLeft]
    return orientation
}

回転させたくないViewController

回転を許容しない設定を埋め込むだけです。

// ## fugafugaViewController.swift

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

これは簡単ですね。

UINavigationControllerにViewControllerがぶら下がっている場合

この場合、UINavigationControllerを拡張して、ぶら下がっているUIViewControllerの設定を取得するようにします。

// ## UINavigationController+Orientation.swift

public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        
    if let _ = self.visibleViewController {
        return self.visibleViewController!.supportedInterfaceOrientations()
    }

    // ViewControllerが無い場合は、縦画面のみ許容します
    let orientation: UIInterfaceOrientationMask = [UIInterfaceOrientationMask.Portrait]
    return orientation
}

public override func shouldAutorotate() -> Bool {
    if let _ = self.visibleViewController {
        return self.visibleViewController!.shouldAutorotate()
    }

    // ViewControllerが無い場合は、回転を許容しません。
    return false
}

これで、UINavigationControllerが子のViewControllerの設定を取得するようになったので、回転を許可したいViewControllerで先程と同じような設定を記述します。

// ## hogehogeViewController.swift

override func shouldAutorotate() -> Bool {
    return true
}
    
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    let orientation: UIInterfaceOrientationMask = [UIInterfaceOrientationMask.Portrait, UIInterfaceOrientationMask.LandscapeRight, UIInterfaceOrientationMask.LandscapeLeft]
    return orientation
}