Browse Questions
  • setNeedsLayout schedules a layout pass for later, layoutIfNeeded forces any pending layout to happen immediately, and setNeedsDisplay schedules a redraw of the view's content.
  • Store tokens securely in the Keychain, attach them to requests via a header, and refresh automatically when a 401 is received.
  • UIStackView arranges views in a horizontal or vertical line and manages all constraints for you.
  • - Inheritance — a class derives behaviour from a parent class ("is-a" relationship) - Composition — a type gets behaviour by holding references to other objects ("has-a" relationship) Swift…

Answer: setNeedsLayout schedules a layout pass for later, layoutIfNeeded forces any pending layout to happen immediately, and setNeedsDisplay schedules a redraw of the view's content. The first two drive layoutSubviews and reposition subviews; the third drives draw(_:) and repaints pixels, and they run at different points in the frame.

Code Example:

// Deferred — coalesced, runs once before the next frame is drawn. Cheap, prefer this.
view.setNeedsLayout()

// Synchronous — flushes the pending layout pass immediately. Use only when you need
// final frames right now (e.g. before measuring, or to animate constraint changes).
view.layoutIfNeeded()

// Redraw content — triggers draw(_:) on the next cycle, not layoutSubviews.
customChartView.setNeedsDisplay()

// The classic constraint-animation idiom:
view.layoutIfNeeded()                 // 1. flush pending layout so we start from a known state
heightConstraint.constant = 200       // 2. change the constraint
UIView.animate(withDuration: 0.3) {
    self.view.layoutIfNeeded()        // 3. animate to the new layout inside the block
}
// Without step 3 the constraint just snaps — constraints animate by animating the layout pass.

// Measuring after a data change
label.text = "New longer text"
label.setNeedsLayout()
label.layoutIfNeeded()
print(label.frame.height)             // now correct; without layoutIfNeeded it's stale

Key Points:

  • Never call layoutSubviews() or draw(_:) directly — mark dirty and let UIKit schedule the pass
  • setNeedsLayout calls are coalesced, so calling it in a loop costs nothing; layoutIfNeeded is real work every time
  • setNeedsUpdateConstraints / updateConstraintsIfNeeded are the same pairing one stage earlier, for updateConstraints()
  • Order per frame: update constraints → layout (layoutSubviews) → display (draw(_:))