はじめに
UIKitでiOSのアプリ開発をしていくなかで必要不可欠な存在であるAuto Layout。
その中でも、制約のPriority
とisActive
は、ビューの配置を制御するための重要なプロパティです。
しかし、この2つの違いを理解して使い分けることは意外と難しいかもしれません。
本記事では、Priority
とisActive
の役割と使い方について解説します。
1. Auto Layoutにおける制約の基本
Auto Layoutは、ビューの位置やサイズを相対的に定義するためのシステムです。
デバイスのサイズや画面の向きに応じてビューを柔軟に配置することができる優れものです。
- 制約 (Constraints): ビューの位置やサイズを定義するルール。画面サイズやデバイスの向きが変わっても、ビューの配置の整合性を保持してくれる
- 制約の優先度 (Priority): 制約がどれほど重要かを示す数値(1〜1000)
- isActiveプロパティ: 制約が現在有効かどうかを示すBool値
2. Priorityの役割
制約の優先度 (Priority
) は、複数の制約が同時に適用された場合に、どの制約が優先されるかを決定します。
通常、Priority
はデフォルトで1000(必須)に設定されていますが、複数の制約が競合する場合にはPriority
を調整することで制約の強さを変更できます。
- 1000 (必須): 常に適用される制約。デフォルトで最も高い優先度
- 1〜999 (任意): 必要に応じて無視される可能性のある制約
Priority
の値が1000の場合、その制約は必ず満たされなければならない必須制約となります。それ以下の値では、他の制約に置き換わる可能性のある任意の制約として扱われます。
例:view1
の先頭がview2
の先頭と一致するように制約を設定し、優先度を999に設定
let constraint = view1.leadingAnchor.constraint(equalTo: view2.leadingAnchor)
constraint.priority = UILayoutPriority(999) // 優先度を999に設定
3. isActiveの役割
isActive
プロパティは、制約が現在有効かどうかを制御します。isActive = true
で制約が有効になり、false
で制約が無効になります。
このプロパティを使うことで、動的に制約を有効化または無効化することが可能です。
-
true
: 制約が有効 -
false
:制約が無効
isActive
を動的に切り替えるときは、レイアウト更新が必要です。一般的に、制約の変更が即座に反映されるようにlayoutIfNeeded
等のView更新処理を呼び出すことが多いです。
例:view1
の先頭がview2
の先頭と一致するように制約を設定し、制約を有効にする
let constraint = view1.leadingAnchor.constraint(equalTo: view2.leadingAnchor)
constraint.isActive = false // 制約を無効化
view.layoutIfNeeded() // レイアウトを更新
4. PriorityとisActiveの違い
- Priority:制約が競合する際の優先度を示し、制約の「重要度」を設定する
- isActive:制約が現在有効かどうかを示し、制約の「有効/無効」を制御する
補足
Priorityを使うときに注意することは、低い優先度の制約が破棄される可能性があるという点です。
例えば、異なるビューに対して競合する制約を持つ場合、Auto Layoutは低い優先度の制約を無視することがあります。
5. 実例で学ぶ: PriorityとisActiveの使い分け
Priority を使うべき場面
-
複数の制約が競合する場合の調整
同じビューに対して複数の制約が存在し、それらが互いに競合する可能性がある場合に、どの制約を優先するかを設定する
例: ビューのサイズを固定したいが、親ビューのサイズが変わる場合にはそのサイズに合わせて伸縮させたい場合
let constraint = view.widthAnchor.constraint(equalToConstant: 100)
constraint.priority = UILayoutPriority(750) // 優先度を750に設定
2. レイアウトの優先順位を調整したいとき
一部の制約が他の制約よりも重要である場合に、その制約の優先度を設定して、レイアウトエンジンにどの制約を優先すべきかを指示する
例: ビューの端にマージンを持たせたいが、画面サイズが小さい場合にはマージンを縮小してでも内容を表示させたい場合
let marginConstraint = view.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 20)
marginConstraint.priority = UILayoutPriority(500) // 優先度を500に設定
3. 制約の重要度を細かく調整したいとき
ビューのレイアウトを細かく調整するために、制約の優先度を設定して柔軟にレイアウトを制御する
例: コンテンツの高さや幅を一定範囲内で変動させたい場合
let flexibleHeightConstraint = view.heightAnchor.constraint(equalToConstant: 200)
flexibleHeightConstraint.priority = UILayoutPriority(250) // 優先度を250に設定
isActive を使うべき場面
-
動的に制約を切り替えたいとき
ユーザーの操作やアプリの状態に応じて、特定の制約を有効/無効にする必要がある場合
例: ボタンをタップしたときにビューの位置やサイズを変更し、特定の条件でビューを表示/非表示を切り替えたい場合@objc func toggleView() { constraint.isActive.toggle() view.layoutIfNeeded() }
-
一時的なレイアウト変更が必要なとき
一時的にビューの配置を変更したい場合や、アニメーションの間だけ異なるレイアウトを適用したい場合
例: メニューを開いた際のコンテンツレイアウトを変更したい場合UIView.animate(withDuration: 0.3) { self.menuConstraint.isActive = !self.menuConstraint.isActive self.view.layoutIfNeeded() }
使い分けのポイント
- Priority: 制約が有効であるときの重要度を設定する。複数の制約が同時に適用される場合や、柔軟なレイアウトを実現したい場合に使用する
- isActive: 制約を完全に有効化/無効化する場合に使用する。ユーザーインターフェースの動的な変更やアニメーションに適している
まとめ
Priority
とisActive
は、それぞれ異なる目的で使用される重要なプロパティです。
Priority
を調整することで制約の競合を管理し、isActive
を使用して制約を動的に有効化または無効化できます。
プロパティを適切に使い分けることで、柔軟で堅牢なレイアウトを実現していきましょう。