iPad
Xcode
iOS
userinterfaceorientation

iOS で Landscape モードのみサポートする

iOSのアプリでランドスケープモードのみをサポートする必要がありました。Xcodeでターゲットを選び、デバイスのオリエンテーションを Landscape LeftLandscape Right に指定します。

次に、UIWindow の root view controller この場合 UINavigationController のサブクラス MyNavigationController とかを用意して、次のメソッドをオーバーライドします。Landscape モードのみとか言いながら、シレっと、topViewControllersupportedInterfaceOrientations を訊ねてそれを返します。

MyNavigationController.swift
class MyNavigationController: UINavigationController {
    // ...
    override var shouldAutorotate: Bool {
        return true
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return self.topViewController?.supportedInterfaceOrientations ?? .landscape
    }
    // ...
}

そして、navigation view controller の root view controller にもこんな風にメソッドをオーバーライドします。

MyViewController.swift
class MyViewController: UIViewController {

    override var shouldAutorotate: Bool {
        return true
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscape
    }

}

さて、実行してみると、iPhone ではランドスケープ固定となるのですが、iPad では View が landscapeportrait に回転が起きてしまいます。Stack Overflow をちょろっと検索しても、だいたいこの辺で良いような事が書いてありました。Application Delegatefunc application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask を実装すればいいという書き込みがありましたが、そもそも、iPad ではそれすら呼ばれません。

諦めて公開質問を作る感じで、検証用プロジェクトを作り GitHub に公開するつもりで準備を始めました。

これがその検証用プロジェクトです。iPad では回転してしまう状態で公開されています。
https://github.com/codelynx/InterfaceOrientation-2018

ところが、これを準備している間に、答えを見つけてしまいました。どんな検索キーワードを使ったか覚えていませんが、検索キーワードで結果が大きく異なるのは少し痛いです。

SupportedInterfaceOrientations not called in iPad

If 'Requires full screen' setting from 'General' is enable, will allow the orientation delegate methods shouldAutorotate, preferredInterfaceOrientation, and supportedInterfaceOrientations to fire.

結果から言うと、info.plistRequire full screenon にしておけば、ちゃんと iPad でもsupportedInterfaceOrientations が呼ばれるようになりました。

Screen Shot 2018-03-16 at 12.12.50 AM.png

その代わり、multitasking な機能が使えなくなると言う話もありますが、ゲームや一部アプリなど大人の事情でランドスケープ固定が望ましいアプリもあるので、それらの場合はこの方法で大丈夫のようです。

試してはいませんが、portrait 固定の場合でも同様かと思います。

執筆時のXcodeとSwiftのバージョンは以下の通りです。

Xcode Version 9.2 (9C40b)
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
Target: x86_64-apple-macosx10.9