30. April 2019

Auto Layout Constraints im Code anlegen

Beim programmatischen Anlegen von Layout-Constraints muss das Übersetzen der Auto-Resizing-Mask in Layout-Constraints deaktiviert werden, da ansonsten die selbst angelegten Constraints mit den automatisch erzeugten Constraints im Konflikt stehen werden:

label.translatesAutoresizingMaskIntoConstraints = false

Alle Views haben Layout-Anchor-Eigenschaften wie topAnchor, leadingAnchor etc., mit denen Constraints komfortabel erstellt werden können. Das erzeugen erfolgt über NSLayoutConstraint.activate([...]).

Beispielsweise wird folgendes View:

Layout-Beispiel

mit folgendem Layout-Code erzeugt:

let view = UIView()
view.backgroundColor = .white

let margins = view.layoutMarginsGuide

let label = UILabel(frame: .zero)
label.backgroundColor = .yellow
label.text = "Hello Layout Constraints"
view.addSubview(label)

let label2 = UILabel(frame: .zero)
label2.backgroundColor = .orange
label2.text = "Another Label"
view.addSubview(label2)

var buttons = [UIButton]()
for i in 1...3 {
    let btn = UIButton(type: .system)
    btn.setTitle("Button \(i)", for: .normal)
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.backgroundColor = .blue
    buttons.append(btn)
}

let stackView = UIStackView(arrangedSubviews: buttons)
stackView.axis = .horizontal
stackView.spacing = 10
view.addSubview(stackView)

stackView.setCustomSpacing(30, after: buttons.first!)

label.translatesAutoresizingMaskIntoConstraints = false
label2.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    label.topAnchor.constraint(equalTo: margins.topAnchor, constant: 10),
    label.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
    label.trailingAnchor.constraint(equalTo: margins.trailingAnchor),

    label2.leadingAnchor.constraint(equalTo: label.leadingAnchor),
    label2.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 10),
    label2.widthAnchor.constraint(equalToConstant: 200),

    stackView.leadingAnchor.constraint(equalTo: label2.leadingAnchor),
    stackView.topAnchor.constraint(equalTo: label2.bottomAnchor, constant: 10)
])