
【Swift4】AutoLayoutをコードで実装してみた!
2021.12.20
AutoLayoutの実装方法について簡単にまとめてみた

(株)ライトコードの高階(たかがい)です!
StoryBoardでのAutoLayoutの実装はできるけど、コードで書いたことない!
そんなあなた(私)のために、コードでの AutoLayout の実装方法について簡単にまとめてみました。
今回は、ライブラリを使わずに標準の方法のみまとめていきます!
開発環境
MacOS | 10.14 |
Swift | 4.2 |
Xcode | 10.1 |
Cocoapods | 1.6.1 |
SnapKit | 4.0 |
AutoLayoutとは?
iOS デバイスの多様な画面サイズに View を適応させるレイアウトの仕組みのことです。
座標やサイズを直接設定せず、相対的な値を View に制約(Constraint)として設定し、表示します。
コードで AutoLayout 実装する方法は、以下の2つの方法があります。
- NSLayoutConstraint
- NSLayoutAnchor
実際に書いて動かした方が早いので早速やっていきます!
が、その前にコードで AutoLayout を実装する際の注意点から。
コードで実装するときに注意するポイント2点
まず最初に注意して欲しいのが、必ず View を配置(addSubView)してから制約を設定すること。
注意点1
配置前に制約を設定すると、実行時に以下のエラーでクラッシュします。
The view hierarchy is not prepared for the constraint:
注意点2
もう一点は、translatesAutoresizingMaskIntoConstraints をオフにすること。
{制約を設定するView}.translatesAutoresizingMaskIntoConstraints = false
Viewを配置する前に上の一行を書いちゃいましょう。
ちなみに、この「translatesAutoresizingMaskIntoConstraints」というプロパティについてですが、AutoLayout 以前に使われていた「Autosizing」というレイアウトの仕組みを、AutoLayout に変換するかどうかを設定するフラグだそうです。

実装について
では、早速それぞれの実装方法を見ていきましょう。
今回は、比較のために以下のように、中央に100pt四方の赤い View を表示させていきたいと思います。

1.NSLayoutConstraint
こちらは、NSLayoutConstraint クラスのイニシャライザを利用した方法です。
イニシャライザの定義は、以下のようになっています。
1 2 3 4 5 6 7 8 9 | public convenience init( item view1: Any, attribute attr1: NSLayoutConstraint.Attribute, relatedBy relation: NSLayoutConstraint.Relation, toItem view2: Any?, attribute attr2: NSLayoutConstraint.Attribute, multiplier: CGFloat, constant c: CGFloat ) |

引数について
たくさんある引数について順に説明していきます。
引数名 | 渡すもの |
item | 追加するView |
attribute(attr1) | 追加するViewの設定をする部分 |
relatedBy | 追加するViewと基準となるViewの関係性 |
toItem | 基準となるView |
attribute(attr2) | 基準となるViewの基準となる部分 |
multipier | 制約の割合の数値 |
contant | 制約で追加する数値 |
仮に、relatedBy を .equal とした時の状態を簡潔に表すと
item.attribute(attr1) = toItem.attribute(attr2) * multiplier + constant
となります。
実際にコードを書いてみる!
以下は、100pt 四方の View を画面中央に表示させるコードです。
引数を色々といじってみた方が理解が早いと思うので、そちらをお試しください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | let view1 = UIView() // 追加するViewを生成 view1.backgroundColor = UIColor().red // 確認用に色を変更 view1.translatesAutoresizingMaskIntoConstraints = false view.addSubview(view1) // 親Viewに配置 view.addConstraints([ // 生成した制約を設定する NSLayoutConstraint( // 制約を生成 item: view1, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 0.0, constant: 100 ), NSLayoutConstraint( item: view1, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 0.0, constant: 100 ), NSLayoutConstraint( item: view1, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1.0, constant: 0.0 ), NSLayoutConstraint( item: view1, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1.0, constant: 0.0 ) ]) |
2. NSLayoutAnchor
次は、iOS9 で追加された NSLayoutAnchor クラスを利用して表示させる方法です。
こちらは、NSConstraint よりも、かなり簡潔に書くことができます。
実際にコードを書いてみる!
NSLayoutConstraint クラスを利用して表示させたものと同じものを表示させるコードが以下になります。
1 2 3 4 5 6 7 8 9 | let view1 = UIView() view1.backgroundColor() = .red view1.translatesAutoresizingMaskIntoConstraints = false view.addSubview(view1) view1.widthAnchor.constraint(equalToConstant: 100).isActive = true // 幅を100ptに設定する制約を有効にする view1.heightAnchor.constraint(equalToConstant: 100).isActive = true // 高さを100ptに設定する制約を有効にする view1.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true // X座標軸の中心を親Viewと合わせる制約を有効にする view1.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true // Y座標軸の中人を親Viewと合わせる制約を有効にする |

Anchor は、View の端や寸法を表すので、Attribute とほぼ同じです。
引数について
Anchor の指定後に constraint メソッドで制約を付与していますが、こちらのメソッドは制約の内容により引数が異なります。
- 値を定数のみで指定したい場合は、equalToConstant: を、Anchorを指定したい場合は、equalTo: を指定する
- 指定したAnchorの値を2倍にしたり1/2にしたい場合は、equalTo: の後にmultiplier: の引数を追加
- 指定したAnchorの値の2倍+10ptなどの指定をしたい場合はmiltiplier: の後にさらにconstant: の引数を追加
最後に制約を生成した後に isActive プロパティを true にしていますが、こちらは生成した制約をレイアウト構築時に反映させるかどうかを制御するフラグになります。

次回の記事に続く
NSLayoutConstraint はさておき、NSLayoutAnchor に関しては、思っていたよりもシンプルで分かり易かったです。
これなら、コードでの AutoLayout も割と楽に書けそうですね。
ただ、AutoLayout をさらに簡単にするライブラリがあるようなので、次の内容ではライブラリについてまとめていきたいと思います!
次の記事
こちらの記事もオススメ!
書いた人はこんな人

IT技術9月 27, 2022LaravelにPHPの静的解析ツールを導入し、コードをきれいに保つ
IT技術5月 13, 2022Laravelフレームワークのバージョンアップを実施する
ライトコードの日常4月 8, 2022YOUは何しにライトコードへ?〜松崎さん編〜
IT技術3月 31, 2022Ruby のテストフレームワーク minitestとRSpec