画面向きの設定に関してずっと勘違いしていた点があったので共有。
UISupportedInterfaceOrientations
ターゲットのDevice orientation設定(plistのUISupportedInterfaceOrientations)は、そのアプリでサポートする画面向きを設定するためだけのもの、という認識だったんですが、正しい定義は、
- 「アプリ起動時の画面向きの初期値」の決定に使用される。
- AppDelegateでapplication:supportedInterfaceOrientationsForWindow:を実装 していない場合 は「アプリ全体でサポートする画面向き」の決定にも使用される
です。
例
以下のような要件のアプリを作りたいとします。
- アプリ起動時直後に表示される画面は、portraitのみ対応する
- それ以外の画面は portrait/landscape両方に対応する
誤った実装
ということでまずは、ターゲット > General > Deployment Info > Device Orientationの設定。アプリ全体としては portrait/landscape両方対応するので、とりあえず以下のように設定してみる。
Storyboardは以下の様な感じ。
初回の画面は portrait 専用ってことでViewControllerを以下のように実装。
class FirstViewController: UIViewController {
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.toRaw())
}
}
さて、これを iPhone6Plusで画面を横向きにした状態 で起動してみましょう。
起動!
landscapeで起動しちゃってるー
ちなみにこの状態で、適当なモーダルviewを persentViewControllerして、すぐにdismissViewControllerすると、再描画がかかって想定どおりportraitで表示されます。キモいですね。
正しい実装
最初にも書いたとおり、UISupportedInterfaceOrientationsは「アプリ起動時の画面向きの初期値」を定義する設定です。FirstViewはportraitのみ対応にしたいので、このように設定するのが正しい。
ただしこの設定をしただけだと、アプリ全体において portrait しかサポートしないことになっちゃうので、AppDelegateでapplication:supportedInterfaceOrientationsForWindowを実装して、アプリ全体としてサポートする向きの設定をしておきましょう。
class AppDelegate: UIResponder, UIApplicationDelegate {
//....
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw())
}
これで、先ほどと同じくiPhone6Plusで画面を横向きにした状態で起動してみると・・・
ちゃんと縦向きで起動してくれました。デバイスを横に倒しても・・
縦向きのままです。
ちなみにFirstView以外は想定通り、縦も
横も、
両方サポートしてます。
まとめ
アプリ起動時直後に表示される画面は、portraitのみ対応、それ以外の画面は portrait/landscape両方に対応、というiPhoneアプリは結構あると思います。iPhone6Plus登場以前のiPhoneは、そもそもホーム画面がlandscape対応してないので、
このように設定したとしても、アプリ起動時においてはこの設定は無視され portraitでそのまま起動するので特に問題にはなりませんでした。しかし、iPhone6Plusはホーム画面がlandscapeに対応しているので、アプリ起動時にしっかりこの設定が適用されてしまうので気をつけましょう、という話でした。
参考
Apple Developer Forumでの議論
https://devforums.apple.com/message/1051638#1051638
plistのUISupportedInterfaceOrientationsキーの定義
https://developer.apple.com/library/IOs/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW10