【Swift5】 特定画面で縦画面/横画面に固定させる

## はじめに
初投稿です。
ついにやってみたかったiPhoneのアプリを完成できました！
その備忘録です〜

## やりたかったこと
ゲーム設定画面は縦、ゲーム画面自体は横画面としたかったので、
画面の向きを判定して、縦だったら横に、横だったら縦に向きを固定する。
※便宜上、
ホームボタン左　= 左横画面
ホームボタン右　= 右横画面　とします。

##やってみたこと
*supportedInterfaceOrientations*の単純な画面の向きを指定だけだと、
自動回転しちゃうのでそれも制御しないとだめなんですよね。

```view.swift
     // 画面の向きを指定
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
            return .portrait
   }

    // 画面を回転させるかどうか
    override var shouldAutorotate: Bool {
             return true
   }

```

単純にこれでいけそう！とか思ってたんですけど、
どうも処理の順番が
shouldAutorotate(自動回転)　→　supportedInterfaceOrientations(向き指定)らしく
自動回転OFF　　　→　縦画面に変更
になって、回転できないんですよね〜とほほ

なので、代案として現在の画面向きを取得して、以下の通りの処理を考えました。

| 画面|現在の画面向き|実装                        |
|:--:|:----------:|:-------------------------:|
| 縦 |縦の場合      | 自動回転OFF                |
| 縦 |横の場合      | 画面向きを縦にして自動回転をOFF |
| 横 |縦の場合      | 画面向きを横にして自動回転をOFF |
| 横 |横の場合      | 自動回転させる               |



##実装コード
###縦画面

```TateViewController.swift
class TateViewController: UIViewController{
    // 自動回転はOFFで縦に固定
    override var shouldAutorotate: Bool {
        //縦画面なので縦に固定
        UIDevice.current.setValue(1, forKey: "orientation")
        return false
       
   }
    override func viewDidLoad() {
     <<Code>>
   }
}
```
画面を縦に固定なら自動回転ON/OFF決めるときに
縦にして自動回転OFFにすればいいじゃん！と思ってゴリ押しでオーバーライドしました。解決！

###横画面

```YokoViewController.swift
class YokoViewController: UIViewController {

  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {   
     //最初の画面呼び出しで画面を右横画面に変更させる。
     UIDevice.current.setValue(3, forKey: "orientation")
     return .landscapeRight
  }
    
   // 画面を自動で回転させるかを決定する。
   override var shouldAutorotate: Bool {
      //画面が縦だった場合は回転させない
     if(UIDevice.current.orientation.rawValue == 1){
          return false
    }
      else{
          return true  
    }
  }
}

```


横画面のほうはちょっとめんどくさくなりました。
**shouldAutorotateは画面回転ごとに呼び出されるので、画面回転すれば、横画面にすることができます。if条件で縦のとき自動回転OFFにすれば、縦に回転しません。**

ただ、最初の画面遷移時に、自動回転OFF→縦画面に変更の順に処理されるので、先に横画面の変更処理をする必要があります。どうしたものか...

####横画面　自動回転先呼び出し
適当にTry&Errorを繰り返してたら、**viewDidLoad()内でprint()することで
画面の自動回転定義(shouldAutorotate)より先に呼び出すことができました。**いい子。

```YokoViewController.swift
     override func viewDidLoad() {
        //画面の向きを変更させるために呼び出す。
        print(supportedInterfaceOrientations)
        <<Code>>
    }
```
####横画面　右左判定
ただ、横向きでまとめてしまうと、現在の画面向きが左横画面なのに、右横画面だと逆向きになってしまいます。なので左横画面とそれ以外で場合分けしました。

```YokoViewController.swift
   override var supportedInterfaceOrientations: UIInterfaceOrientationMask {   
      //左横画面に変更
      if(UIDevice.current.orientation.rawValue == 4){
             UIDevice.current.setValue(4, forKey: "orientation")
             return .landscapeLeft    
     }
       //左横画面以外の処理
      else {
              //右横画面に変更させる。
              UIDevice.current.setValue(3, forKey: "orientation")
              return .landscapeRight
     }
 }
```

それでうまく行くと思いきや、前画面で縦に指定しているので
画面向き判定が「縦」になってしまいます。なので強制的に右向き画面になります。こまった。


####横画面　左横画面にセット

そこでviewDidLoad()内で以下の処理をします。

```YokoViewController.swift

     override func viewDidLoad() {
     //画面向きを左横画面でセットする
     UIDevice.current.setValue(4, forKey: "orientation")
        
     //画面の向きを変更させるために呼び出す。
     print(supportedInterfaceOrientations)
     <<Code>>
   }
```

縦画面で遷移している前提ですが、**一度強制的に左横画面にセットします。**
**自動回転は縦画面でなければ、回転するので左横画面になった後右横画面に自動的に回転します。**解決！

以下横画面のソースコード全文です。

```YokoViewController.swift
class YokoViewController: UIViewController {

  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {   
     //左横画面に変更
       if(UIDevice.current.orientation.rawValue == 4){
              UIDevice.current.setValue(4, forKey: "orientation")
              return .landscapeLeft    
      }
       //左横画面以外の処理
       else {
              //最初の画面呼び出しで画面を右横画面に変更させる。
              UIDevice.current.setValue(3, forKey: "orientation")
              return .landscapeRight
      }
 }
    
   // 画面を自動で回転させるかを決定する。
   override var shouldAutorotate: Bool {
      //画面が縦だった場合は回転させない
      if(UIDevice.current.orientation.rawValue == 1){
           return false
     }
       else{
           return true  
     }
  }
   override func viewDidLoad() {
     //画面向きを左横画面でセットする
     UIDevice.current.setValue(4, forKey: "orientation")
        
     //画面の向きを変更させるために呼び出す。
     print(supportedInterfaceOrientations)
     <<Code>>
  }
}  
```
なんとかできました。

##参考にした記事

<https://qiita.com/orimomo/items/6ab57c6706a8dbc181a1>