8
4

More than 3 years have passed since last update.

トレイトコレクションとレイアウト

Posted at

趣味でiOSアプリ開発をかじっていた自分が、改めてiOS開発を勉強し始めた際に、曖昧に理解していたところや知らなかったところをメモしています。いつか書き直します。

参考文献

この記事は以下の書籍の情報を参考にして執筆しました。

トレイトコレクション

トレイトコレクションは表示に関わるアプリの状態管理をしていて、レイアウトを決定するための情報を提供してくれる。
トレイトコレクションの状態に合わせてレイアウトを変更することで柔軟なレイアウトを作れる。
トレイトコレクションはスクリーンで定義されウィンドウからビューコントローラに渡されていく。

image.png

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つのステップに分かれている。

image.png

最初のセットアップ時に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の時のみオブジェクトが適用される。

image.png

image.png

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4