なんとかするから、なんとかなる

エンジニア関係のことを書きます

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を使っていました。

github.com

しかし、最近は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
} ()