以前、Auto Layoutをコードで書いて、その考え方を知るという記事を書きました。
http://qiita.com/shindooo/items/f0259f1be59591503dc1
そのときはSwift 2.2で書いたのですが、Swift 3.0でAPIが一部変更されています(考え方は同じです)。
Swift 3の書き方でNSLayoutAnchorの使い方を再度まとめたいと思います。
Auto Layoutの考え方
Auto Layoutでは「制約(Constraint)」を設定することで、ビューの位置やサイズの決定します。
制約は、位置・サイズについてビュー同士の相対的な関係を定義したものです。
相対的な関係というのは
緑のビューの幅は、青のビューの幅を1.5倍して30pt加えた大きさである
というようなことです。
このことを数式で表すと次のようになります。
greenView.width = 1.5 × blueView.width + 30
さらに一般的に書くと
y = ax + b
簡単な一次関数ですね。この式は非常に重要であり、制約の本質を表しています。
制約を定義するということは、この式の各要素を指定するということになります。
###事前準備
次のようにコードでビューを追加します。
let blueView = UIView()
blueView.backgroundColor = UIColor.blue
blueView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blueView)
AutoresizingMaskをAuto Layoutに変換しないよう、translatesAutoresizingMaskIntoConstraintsをfalseにしておくとよいでしょう(このあと追加する制約とコンフリクトさせないため)。
###NSLayoutAnchorを使う
では早速、NSLayoutAnchorを使った例を見てみましょう。
let leadingConstraint = blueView.leadingAnchor.constraint(equalTo:self.view.leadingAnchor, constant: 30.0)
上記は
青のビューの左端は、親ビューの左端から30ptの位置である
という制約です。
この制約を有効にするには以下のように
leadingConstraint.isActive = true
とします。
これは、つぎのように1行で書くこともできます。
blueView.leadingAnchor.constraint(equalTo:self.view.leadingAnchor, constant: 30.0).isActive = true
以下、簡単なサンプルを載せておきます。
override func viewDidLoad() {
super.viewDidLoad()
let blueView = UIView()
blueView.backgroundColor = UIColor.blue
blueView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blueView)
let greenView = UIView()
greenView.backgroundColor = UIColor.green
greenView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(greenView)
// 青のビューの左端は、親ビューの左端から30ptの位置
blueView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 30.0).isActive = true
// 青のビューの縦方向の中心は、親ビューの縦方向の中心と同じ
blueView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
// 青のビューの幅は、親ビューの幅の1/4
blueView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.25).isActive = true
// 青のビューの高さは30pt
blueView.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
// 緑のビューの左端は、青のビューの右端から20ptの位置
greenView.leadingAnchor.constraint(equalTo: blueView.trailingAnchor, constant: 20.0).isActive = true
// 緑のビューの上端は、青のビューの上端と同じ位置
greenView.topAnchor.constraint(equalTo: blueView.topAnchor).isActive = true
// 緑のビューの幅は、青のビューの幅を1.5倍して30pt加えた大きさ
greenView.widthAnchor.constraint(equalTo: blueView.widthAnchor, multiplier: 1.5, constant: 30.0).isActive = true
// 緑のビューの高さは、青のビューの高さと同じ大きさ
greenView.heightAnchor.constraint(equalTo: blueView.heightAnchor).isActive = true
}