iOS9からNSLayoutAnchorが登場し、NSLayoutConstraintを利用してレイアウトの制約を作成するより、簡単でわかりやすくなりました。
とは言っても、いざ複数の部品で構成される画面を作成するとなると、面倒になるのでStoryboardで制約を設定していくことの方が多いかと思います。
多くの場合は、StoryboardでAutoLayoutの制約を設定して終わることが多いのですが、今回、画面を作成するにあたって、TableViewのセルごとに制約を変更する場面が出てきたので、Storyboardでの制約を設定をなるべく使って必要なところだけソースコードでのAutoLayoutの切り替えを行いましたので、その内容をまとめたいと思います。
環境
Xcode10.2(Swift5.0)の環境で内容をまとめます。
1.画面構成
以下の画面を元に、AutoLayout制約の切り替えを説明します。
画面イメージ |
---|
画面はTableViewで作成されていますが、セルによってレイアウト情報があり、タイトルの縦の位置が左下になったり、中央になったりします。
横の位置のAutoLayoutの制約は常に中央にしておいて、縦の位置のAutoLayoutの制約は、NSLayoutAnchorでいう下の制約(bottomAnchorの設定)と中央の制約(centerYAnchor設定)を切り替えることにより、タイトルの左下/中央の位置を切り替えます。
(画面のタイトルは左下と中央でフォントサイズやアライメントが変更されていますが、その説明はここでは省略します。)
2.Storyboardでの設定
はじめは、ソースコードでレイアウト情報によってタイトルの位置の左下と中央の制約の書いて、切り替えようと思いました。ただ、AutoLayoutの制約は普段Storyboardで設定することが多く、あまりソースコードで書き慣れていないのと、今後レイアウト情報が増えてタイトルの位置が追加となった場合にちょっと面倒と思い、ふとStoryboardで制約を作っておいて切り替えられないかなと考えました。
そうしていろいろ調べたところ、Storyboardの制約の設定にinstalledという項目(以下の画面イメージ右の赤枠を参照)があり、いくつか適用したい制約を作っておいて、このinstalledの項目を1つだけチェックを付けておくことで、1つの制約だけをアクティブに、その他の制約は非アクティブにしておくことができます。(複数制約を作るとコンフリクトしますので、1つの制約だけをアクティブにしておきます。)
非アクティブになっている制約は、画面イメージの左の赤枠のようにアイコンの色が薄くなります。
3.ソースコードでの制約切り替え
StoryboardでAutoLayoutの制約を作成したら、後はレイアウト情報によってソースコードで制約を切り替えます。
以下はサンプルコードです。
@IBOutlet weak var stackViewBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewCenterYConstraint: NSLayoutConstraint!
// (途中省略) //
func updateTitlePosition() {
// タイトルとリンクボタンの表示位置
switch position {
case .center:
stackViewBottomConstraint.isActive = false
stackViewCenterYConstraint.isActive = true
case .bottomLeft:
stackViewCenterYConstraint.isActive = false
stackViewBottomConstraint.isActive = true
}
}
作成した制約はIBOutletで制約のプロパティに接続しておきます。updateTitlePosition
のメソッド内レイアウト情報(position)によって、isActiveプロパティでアクティブと非アクティブを切り替えることでタイトルの位置を変更しています。
これで、ちょっとややこしい制約の設定はStoryboardで設定して、切り替え自体はソースコードで記載できるので、簡単にできるかと思います。