趣味でiOSアプリ開発をかじっていた自分が、改めてiOS開発を勉強し始めた際に、曖昧に理解していたところや知らなかったところをメモしています。いつか書き直します。
参考文献
この記事は以下の書籍の情報を参考にして執筆しました。
#トレイトコレクション
トレイトコレクションは表示に関わるアプリの状態管理をしていて、レイアウトを決定するための情報を提供してくれる。
トレイトコレクションの状態に合わせてレイアウトを変更することで柔軟なレイアウトを作れる。
トレイトコレクションはスクリーンで定義されウィンドウからビューコントローラに渡されていく。
##UITraitCollectionのプロパティ
プロパティ | 型 | 役割 | 値 |
---|---|---|---|
displayScale | CGFlat | 表示スケール | 非Retina:1.0, Retina:2.0, 指定なし:0.0 |
horizontalSizeClass | UIUserInterfaceSizeClass | 水平方向の抽象的なサイズ | Unspecified, Compact, Regular |
verticalSizeClass | UIUserInterfaceSizeClass | 垂直方向の抽象的なサイズ | Unspecified, Compact, Regular |
userInterfaceIdiom | UIUserInterfaceIdiom | 端末種別 | Unspecified, Phone, Pad, TV |
forceTouchCapability | UIForceTouchCapability | 3Dタッチフラグ | Unknown, Unavailable, Availavle |
####サイズクラス
端末と向き | 高さ | 幅 |
---|---|---|
iPad縦 | Regular | Regular |
iPad横 | Regular | Regular |
iPhone縦 | Regular | Compact |
iPhone横 | Compact | Compact |
iPhonePlus縦 | Regular | Compact |
iPhonePlus横 | Compact | Regular |
##UITraitCollectionを比較する
containsTraits(: )メソッドを呼び出して比較する。
引数のトレイトコレクションを含んでいればtrueを返す。
// HorizontalSizeClass = Regular という値のみを持つトレイトコレクションを作成
let regularWidthTrait = UITraitCollection(horizontalSizeClass: .compact)
// self.traitCollection.HorizontalSizeClass == Compact の時trueを返す
print(self.traitCollection.containsTraits(in: regularWidthTrait)) // true
##UITraitCollectionを合成する
init(traitsFrom: )を用いて、トレイトコレクッションの配列を合成したトレイトコレクションを生成できる。
下記の例ではビューコントローラーの持つトレイトコレクションのhorizontalSizeClassをregularに上書きしたトレイトコレクションを生成する例。
let regularWidthTrait = UITraitCollection(horizontalSizeClass: .regular)
let overrideTraitCollection = UITraitCollection(traitsFrom: [self.traitCollection, regularWidthTrait])
##端末の回転挙動を扱う
端末の回転挙動は以下の4つのステップに分かれている。
最初のセットアップ時にUITraitEnvironmentプロトコルとUIContentContainerプロトコルで定義されたメソッドたちが呼び出され、これらのメソッド内で回転挙動を扱うことができる
####willTransition
トレイトコレクションが変化する直前かつ端末の回転時サイズクラスが変化する時に呼び出される。
サイズが変化しない場合、180°回転時やiPadのように縦横のsizeが同じ場合は呼ばれない。
トレイトコレクションはボトムアップに変更されていくので、トレイトコレクションの変更を子ビューコントローラに反映させる為にオーバーライドするときはsuperを呼ぶ必要がある。
####viewWillTransition
アプリを表示しているウィンドウの大きさが変化する直前に呼ばれる。
トレイトコレクションの変更に関係せず表示画面サイズが変更されるときに呼び出されるので180°回転時やiPadでも呼び出される。
このメソッドも変更を子ビューコントローラに反映させる為にオーバーライドするときはsuperを呼ぶ必要がある。
####taritCollectionDidChange
トレイトコレクションが変化した直後またトレイトコレクションがセットされた後に呼び出される。
アプリ起動時やビューコントローラが初めてロードされた時も呼び出される。
このメソッドも変更を子ビューコントローラに反映させる為にオーバーライドするときはsuperを呼ぶ必要がある。
##端末回転時のアニメーション
端末回転時にレイアウトを変更するだけなら上記3つのどのメソッド内に処理を書いても問題はないが、アニメーションと同期してオブジェクトを動かす場合はwillTransition,viewWillTransitionを使う。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { context in
if (size.width <= size.height){
// 縦画面レイアウト用にアニメーションさせたい処理
print("tate")
} else {
// 横画面レイアウト用にアニメーションさせたい処理
print("yoko")
}
}, completion: nil)
}
##各オブジェクトごとにサイズクラスを適用する
下記のように設定するとWidthがRegular、HeightがCompactの時のみオブジェクトが適用される。