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

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

iOS How to set the Autolayout programatically

Introduction

It was difficult and complexity to set the autolayout programatically when the AutoLyaout announced in iOS

NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true

That was because I used to use Snapkit(OSS).

github.com

But, these days, it will easy to set the autolayout programatically.

I'll introduce the method of setting autolayout programatically.

How to set the autolayout programatically

For example, if you want to the view at the bottom of the self.view, you can easy to set it below.

Code

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

Attention

order to calling the addSubview()

If you register the constraint to self.view before calling addSubview method, the app will crash.

Don't forget setting the translatesAutoresizingMaskIntoConstraints

If you forget to set the translatesAutoresizingMaskIntoConstraints to false, the constraint will not working.

Don't forget setting "isActive = true"

If you forget to set the isActive propery, the constraint will not working.

How to set the autolayout to SafeArea programatically

To set the autolayout to Safeare, you can use 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
}

How to make a margin related with other view's height by ration.

If you want to set the UIButton at the top of self.view with margin "self.view.frame.size.height * 0.3", you can use the UILayoutGuide.

In programatically autolayout setting, it not need to use UIView for spacer anymore.

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

Finally

I'll show the whole code to initialize the UIButton instance and set the autolayout programatically.

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
} ()