表題通り。
ハマった。
UICollectionViewLayout に関して調べると、 UICollectionViewFlowLayoutとかUICollectionViewDelegateの話がごっちゃになって調べるのが難しいから余計に時間かかってしまた...
内容
- UICollectionView Layout を使ってる場合に、画面を回転したときにサイズが変わらないと苦しんだ
- UICollectionViewLayoutは自分でセルサイズや位置を調節できるため、その処理も書かないといけなかった
- 以下コードでは画面回転をUIViewControllerを継承してるクラスで画面回転を察して、invalidateLayout()を動かす前に1列当たりのセル数を更新してる。
コード
PintaLayout.swift
class PintaLayout: UICollectionViewLayout {
/// 1列当たりのセル数を定義する。
var numberOfColumns = 2
override func prepare() {
super.prepare()
makeLayout()
}
func makeLayout() {
// TODO: ここにサイズを計算する処理を書く
// TODO: numberOfColumns を使って横向きにいくつ配置するか計算する
}
override func invalidateLayout() {
// TODO: makeLayout()で計算したサイズがあれば削除
makeLayout()
super.invalidateLayout()
}
}
MyViewController.swift
class MyViewController:UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
/// 縦の時は1列、横の時は2列となるようにする。
/// iPadは2列固定。
var numberOfColumns: Int {
get {
if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad {
return 2
}
if view.frame.width < view.frame.height {
return 1
}
return 2
}
}
override func viewDidLoad() {
super.viewDidLoad()
// TODO: セルの追加
// collectionView.register(UINib.init(nibName:.......
collectionView.delegate = self
collectionView.dataSource = self
if let layout = collectionView.collectionViewLayout as? PintaLayout {
layout.delegate = self
layout.numberOfColumns = numberOfColumns
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
guard let flowLayout = collectionView.collectionViewLayout as? PintaLayout else {
return
}
coordinator.animate(alongsideTransition: { (_) in
// 画面回転したら、invalidateLayout()を呼び出すが、その前に画面回転時に更新する1列当たりのセル数を調節する
flowLayout.numberOfColumns = self.numberOfColumns
flowLayout.invalidateLayout()
}, completion: nil)
}
}