iPhone6Plusと初回起動時の画面向きについて

画面向きの設定に関してずっと勘違いしていた点があったので共有。

# UISupportedInterfaceOrientations 

ターゲットのDevice orientation設定（plistのUISupportedInterfaceOrientations）は、そのアプリでサポートする画面向きを設定するためだけのもの、という認識だったんですが、正しい定義は、

* 「アプリ起動時の画面向きの初期値」の決定に使用される。
* AppDelegateでapplication:supportedInterfaceOrientationsForWindow:を実装 **していない場合** は「アプリ全体でサポートする画面向き」の決定にも使用される

です。

# 例

以下のような要件のアプリを作りたいとします。

* アプリ起動時直後に表示される画面は、portraitのみ対応する
* それ以外の画面は portrait/landscape両方に対応する

## 誤った実装

ということでまずは、ターゲット > General > Deployment Info > Device Orientationの設定。アプリ全体としては portrait/landscape両方対応するので、とりあえず以下のように設定してみる。

![スクリーンショット 2014-10-07 17.33.22.png](https://qiita-image-store.s3.amazonaws.com/0/8399/ba7e2520-ea92-d40e-9f34-ba9fec41b47c.png)

Storyboardは以下の様な感じ。

![スクリーンショット 2014-10-07 16.54.36.png](https://qiita-image-store.s3.amazonaws.com/0/8399/92018409-d517-7fd5-1ea0-c1fed5ac2da2.png)

初回の画面は portrait 専用ってことでViewControllerを以下のように実装。

```objc:FirstViewController.swift
class FirstViewController: UIViewController {

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

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.toRaw())
    }
}
```

さて、これを **iPhone6Plusで画面を横向きにした状態** で起動してみましょう。

![iOS Simulator Screen Shot 2014.10.07 16.53.34.png](https://qiita-image-store.s3.amazonaws.com/0/8399/edd4435b-c625-8dab-c9a2-1c3af741a5ae.png)

起動！

![iOS Simulator Screen Shot 2014.10.07 16.54.10.png](https://qiita-image-store.s3.amazonaws.com/0/8399/645feae0-b0f6-3f09-8832-c460a355342f.png)

landscapeで起動しちゃってるー

ちなみにこの状態で、適当なモーダルviewを persentViewControllerして、すぐにdismissViewControllerすると、再描画がかかって想定どおりportraitで表示されます。キモいですね。

## 正しい実装

最初にも書いたとおり、UISupportedInterfaceOrientationsは「アプリ起動時の画面向きの初期値」を定義する設定です。FirstViewはportraitのみ対応にしたいので、このように設定するのが正しい。

![スクリーンショット 2014-10-07 16.59.30.png](https://qiita-image-store.s3.amazonaws.com/0/8399/6b353523-41a8-eff9-a15a-d8b7c8ca6c8d.png)

ただしこの設定をしただけだと、アプリ全体において portrait しかサポートしないことになっちゃうので、AppDelegateでapplication:supportedInterfaceOrientationsForWindowを実装して、アプリ全体としてサポートする向きの設定をしておきましょう。

```objc:AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    //....

    func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
        return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw())
    }
```

これで、先ほどと同じくiPhone6Plusで画面を横向きにした状態で起動してみると・・・

![iOS Simulator Screen Shot 2014.10.07 17.29.41.png](https://qiita-image-store.s3.amazonaws.com/0/8399/f8608cfa-c8da-e127-0caf-ad3e61703034.png)

ちゃんと縦向きで起動してくれました。デバイスを横に倒しても・・

![iOS Simulator Screen Shot 2014.10.07 17.29.43.png](https://qiita-image-store.s3.amazonaws.com/0/8399/999817d9-0404-0c71-527b-061f379537a5.png)

縦向きのままです。

ちなみにFirstView以外は想定通り、縦も

![iOS Simulator Screen Shot 2014.10.07 17.29.46.png](https://qiita-image-store.s3.amazonaws.com/0/8399/0671a1c1-fb18-336c-b63c-20ea754ab3ac.png)

横も、

![iOS Simulator Screen Shot 2014.10.07 17.29.48.png](https://qiita-image-store.s3.amazonaws.com/0/8399/affac32c-9e46-015a-b7e1-399dfefc1505.png)

両方サポートしてます。

# まとめ

アプリ起動時直後に表示される画面は、portraitのみ対応、それ以外の画面は portrait/landscape両方に対応、というiPhoneアプリは結構あると思います。iPhone6Plus登場以前のiPhoneは、そもそもホーム画面がlandscape対応してないので、
 
![スクリーンショット 2014-10-07 17.33.22.png](https://qiita-image-store.s3.amazonaws.com/0/8399/ba7e2520-ea92-d40e-9f34-ba9fec41b47c.png)

このように設定したとしても、アプリ起動時においてはこの設定は無視され 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