Skip to main content

State Updates

When the state of a view changes, call setNeedsLayout to trigger a layout update. This applies whether you're using the @QuickLayout macro or manual integration.

With the @QuickLayout macro, calling setNeedsLayout will:

  • Update the view hierarchy based on the current state
  • Animate any views that are added or removed
  • Re-layout all subviews

The example below demonstrates a stateful view that lazily creates a label when the user presses the increaseButton for the first time, and updates the layout accordingly.

@QuickLayout
final class CounterView: UIView {

private var count = 0

private lazy var label {
// This view will only be created when the count is set to 1 for the first time.
UILabel()
}

private lazy var increaseButton = {
let button = UIButton(type: .system)
button.setTitle("Increase", for: .normal)
button.addTarget(self, action: #selector(addCount), for: .touchUpInside)
return button
}()

private lazy var resetButton = {
let button = UIButton(type: .system)
button.setTitle("Reset", for: .normal)
button.addTarget(self, action: #selector(resetCount), for: .touchUpInside)
return button
}()

var body: Layout {
VStack(spacing: 8) {
if count > 0 {
label
}
HStack(spacing: 8) {
increaseButton
resetButton
}
}
}

@objc private func addCount() {
count += 1
label.text = "Count: \(count)"
setNeedsLayout() // <-- This is the key line.
}

@objc private func resetCount() {
count = 0
setNeedsLayout() // <-- This is the key line.
}
}