iOS AutoLayoutをコードから設定する方法
English version below
はじめに
AutoLayoutが発表された当初、AutoLayoutをコードから設定するのは面倒でした。
NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
つらい。
そこでよくSnapKitというOSSを使っていました。
しかし、最近はOSSを使わなくとも簡単に設定することができるため、その方法を備忘録として
やり方
viewの下端にUIButtonを設置したい場合は、次のように設定します。
コード
let button = UIButton() self.view.addSubview(button) button.translatesAutoresizingMaskIntoConstraints = false button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true button.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.06).isActive = true button.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.7).isActive = true button.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20).isActive = true
注意点
addSubview()の順番
addSubviewでSubviewに登録する場合にconstraitを設定すると落ちます。
translatesAutoresizingMaskIntoConstraintsの設定忘れ
translatesAutoresizingMaskIntoConstraintsをfalseに設定しないと制約が反映されません。
isActive = trueの設定忘れ
isActiveを設定しないと制約は有効になりません。
SafeAreaの設定方法
セーフエリアの設定には、safeAreaLayoutGuideを使用します。
if #available(iOS 11, *) { button.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -20).isActive = true } else { button.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20).isActive = true }
viewに対する比率を指定して空き(マージン)を作る
AutoLayoutを使用していると、例えばUIButtonをviewの高さ1/3のところに設定したい。
など、あるViewに対する比率分空けたいなど比率を指定したいこともあります。
その場合はUILayoutGuideを使います。
空欄のUIViewを置くという方法もありますが、私はあまり好きではないです。
次のコードはUIButton(self.button)をViewの下部から高さ*0.2空けて表示するときのUILayoutGuideです。
let spacer = UILayoutGuide() self.view.addLayoutGuide(spacer) spacer.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true spacer.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true spacer.topAnchor.constraint(equalTo: button.bottomAnchor).isActive = true
最後に
最後にコード全体と示します。 UIButtonを宣言して、Autolayoutを設定するまでのコードです。
lazy var mybutton: UIButton = { let button = UIButton() self.view.addSubview(button) button.translatesAutoresizingMaskIntoConstraints = false button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true button.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.06).isActive = true button.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.7).isActive = true let spacer = UILayoutGuide() self.view.addLayoutGuide(spacer) spacer.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true spacer.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true spacer.topAnchor.constraint(equalTo: button.bottomAnchor).isActive = true return button } ()