← All topics/UIKit & SwiftUI internals

Practical interview questions

Scenario-style prompts with sample answer outlines. Focus is on how you would design and reason in real codebases.

Question 1

View bounds and layout timing

Where do common mistakes happen when reading view bounds or forcing layout too early?

Follow-ups

  • When is viewDidLoad the wrong place to read view.bounds?

Answer outline

Bounds and layout mistakes cluster around three patterns:

  1. 1.Bounds read too early — in viewDidLoad, view.bounds is often not final. The system hasn’t finished layout for the current orientation, safe area, or container size. Setting layer frames or clipping paths from those values gives wrong sizes until something forces a relayout.
  2. 2.layoutIfNeeded() as a band-aid — sprinkling it to silence ambiguous constraint warnings masks the real problem and can add extra layout passes. Fix the constraints. Calling it in viewDidLoad before the view hierarchy is in a window still yields stale geometry.
  3. 3.One-time safe area readssafeAreaInsets can change after viewDidLoad when bars show or hide, on rotation, in split view, or inside a custom container. Don’t cache a single read at load time; use view.keyboardLayoutGuide for keyboard avoidance on modern iOS.

Prefer Auto Layout constraints wherever possible — they stay correct across rotations, safe area changes, and container transitions without manual pixel work.

Principles

  • Treat viewDidLoad as wiring and subview creation — not the moment of truth for final frames.
  • Read geometry and position layers in viewDidLayoutSubviews (after super) when pixels are required.
  • layoutIfNeeded() is a timing tool for animating constraint changes — not a fix for ambiguous layout.
  • safeAreaInsets are not stable at load time — respond to changes rather than reading once.
Geometry-dependent work — defer to viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // bounds now match container + safe area for this pass
    gradientLayer.frame = view.bounds
}

The legitimate use is driving a constraint animation, not papering over missing constraints:

Correct use of layoutIfNeeded() — animate a constraint change
heightConstraint.constant = 200
UIView.animate(withDuration: 0.3) {
    self.view.layoutIfNeeded()  // animates the constraint change
}

Follow-up angles

  • SwiftUI: avoid assuming one-shot size in onAppear; use GeometryReader / onGeometryChange when layout depends on proposed size.