画面遷移後に画面回転された際の遷移元画面のレイアウト調整


#おさらい
画面の縦横回転をする時には、Notificationを使用することで回転のタイミングで、何か処理をすることが出来ます。

```swift:Notification

// NotificationCenterに画面回転を追加
private func registerNotification() {   
	NotificationCenter.default.addObserver(self,
										   selector:#selector(didChangeOrientation(_:)),
										   name: .UIDeviceOrientationDidChange, 
										   object: nil)
    
}
    
@objc private func didChangeOrientation(_ notification: Notification) {
	//画面回転のイベント
}

```

##使用例
例えば、UICollectionViewに縦横関係なく、10*4で40個ぴったり表示されるようなレイアウトをするとすれば、

```swift

// UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
 	return CGSize(width: collectionView.frame.width/10, height: collectionView.frame.height/4)
}

// Notification
@objc private func didChangeOrientation(_ notification: Notification) {
	//画面回転のイベント
 	collectionView.reloadData()
}

```

こんな感じになるわけですね。🐸
![rotate1](https://user-images.githubusercontent.com/20692907/36068701-08778d62-0f1f-11e8-824c-3e9d42e4a906.gif)

#画面遷移した場合
今回は画面遷移後に、画面を回転すると、先ほどの使用例のようなレイアウトでおかしくなってしまいました。

##大丈夫なパターン
まずは、先ほどの使用例の状態で、画面遷移した後、遷移後画面で、画面の回転をして、画面を閉じるとこうなります。
![rotate2](https://user-images.githubusercontent.com/20692907/36068786-fcaf3956-0f20-11e8-91c0-ba8f48b5565b.gif)

遷移元(縦)→遷移後(横)
遷移元(横)→遷移後(縦)
のどちらのパターンでもうまくCollectionViewがリロードされてサイズ調整されています。

##ダメなパターン
今度は、以下のように枠線付きにしてみましょう。
![2018-02-11 11 38 02](https://user-images.githubusercontent.com/20692907/36068807-aeebdfb6-0f21-11e8-80e7-a1537be25ed0.png)
大元のUIViewに配置していたUICollectionViewを黒の枠線の色を付けたUIViewのSubViewとして配置し、上下左右に10ptの制約を付与します。
![2018-02-11 11 50 57](https://user-images.githubusercontent.com/20692907/36068816-db7bd69e-0f21-11e8-909c-e81eed4ebf05.png)

UICollectionViewのセルのサイズが遷移前の画面の向きのまま更新されません。
![rotate3](https://user-images.githubusercontent.com/20692907/36068869-93c1c42a-0f22-11e8-95e7-668917b1f2c2.gif)


#やってみたこと
##1.layoutIfNeeded
まずは、画面が隠れている時でもNotificationの処理は実行されるので、画面が隠れているときに大元のViewのframeの大きさが変わっていないが故にセルのサイズが変わってないのではないかと疑ってみました。

```swift
@objc private func didChangeOrientation(_ notification: Notification) {
	print("frame:\(view.frame)")
   	collectionView.reloadData()
}
```

すると、画面遷移後はViewの大きさが遷移時から変わっていないことに気づきました。
![2018-02-11 12 08 13](https://user-images.githubusercontent.com/20692907/36068967-47c792be-0f24-11e8-9fdf-ad4d95d1d1b4.png)

ということはlayoutIfNeededすれば正しいViewのサイズに更新されてうまくいくのでは？と思いやってみました。

```swift
@objc private func didChangeOrientation(_ notification: Notification) {
	view.layoutIfNeeded()
  	collectionView.reloadData()
}
```

![2018-02-11 12 12 08](https://user-images.githubusercontent.com/20692907/36068996-db94b8fa-0f24-11e8-94ae-a4b347bf6002.png)

![4ef37896](https://user-images.githubusercontent.com/20692907/36069018-155fd38a-0f25-11e8-8bb1-c53e90d72cee.jpg)

##2.viewDidAppear/viewDidLayoutSubviews
「UIView orientation frame not change」とかで調べると、viewDidAppearとかviewDidLayoutSubviewsだったらframe更新されてるからそこで更新しろみたいなことを書いてたんですが、「いや、それ今回のパターンの場合、一瞬ダメな方のレイアウト出てくるくない？まあでもやるだけやってみるか」と思い試してみました。

![rotate4](https://user-images.githubusercontent.com/20692907/36069092-72fb0482-0f26-11e8-9b0a-ce671142fb22.gif)

![2018-02-11 12 41 28](https://user-images.githubusercontent.com/20692907/36069235-fa9b172c-0f28-11e8-931e-af1ca9b932d1.png)

**いや、わかってたけども。**

##3.手動でViewを更新
大元のUIViewのサイズをUIScreenのサイズに手動更新してみることにしました。

```swift
override func viewWillAppear(_ animated: Bool) {
	super.viewWillAppear(animated)
   	view.frame.size = UIScreen.main.bounds.size
   	view.layoutIfNeeded()
}
```

![rotate5](https://user-images.githubusercontent.com/20692907/36069177-10f82416-0f28-11e8-911f-ae34a5e736bc.gif)

![2018-02-11 12 41 38](https://user-images.githubusercontent.com/20692907/36069234-fa787898-0f28-11e8-9686-82ac40477a39.png)


**おしまい**

追記:[Githubにサンプルあげた](https://github.com/PKPK-Carnage/RotateUpdateSample)