UIKit & Rendering
UIKit is the imperative, object-oriented framework most production iOS apps still run on, even as SwiftUI grows. Where SwiftUI describes a screen declaratively, UIKit has you build it by hand — a tree of UIView objects owned by a UIViewController, mutated in place, always on the main thread. Understanding it means holding three mental models at once: the view hierarchy and the responder chain that routes touches through it, the Auto Layout and rendering pipeline that turns constraints into pixels, and the app lifecycle that decides when your code even gets to run.
The recurring interview theme is the invisible machinery underneath the ordinary-looking API. A cell is not freshly allocated on every scroll — it is recycled from a pool, and forgetting to reset it paints the wrong row. A constraint is not a fixed frame — it is one equation in a system the layout engine solves. setNeedsLayout does not lay out immediately — it marks the view dirty for the next pass. Miss these schedules and you get jank, wrong-image bugs, and undefined behaviour when you touch UIKit off the main thread.
Topic map
- UIKit fundamentals — the view hierarchy and
UIViewvsCALayer, the view-controller lifecycle, the responder chain, cell reuse and the reuse bug, target-action and delegation, and the main-thread rule. - Auto Layout & rendering — constraints as a linear system, intrinsic content size, hugging vs compression resistance, the layout/display cycle,
framevsbounds, and the cost of offscreen rendering. - App lifecycle — the five app states and their callbacks, the scene-based lifecycle, background execution, the launch sequence, and memory warnings.
Common traps
| Mistake | Consequence |
|---|---|
Reusing a dequeued cell without resetting it in prepareForReuse | Stale text or an image from another row paints on the wrong cell |
| Touching UIKit off the main thread | Undefined behaviour — visual glitches, crashes, or nothing, at random |
| Treating a constraint as a fixed frame | You can't reason about why a layout is ambiguous or over-constrained |
Calling layoutSubviews directly | Bypasses the scheduled pass; use setNeedsLayout / layoutIfNeeded |
Rounding corners with cornerRadius + masksToBounds on scrolling cells | An offscreen render pass per frame blows the frame budget |
Assuming didFinishLaunching means the UI is on screen | Scene callbacks own window setup; per-window work is misplaced |
Interview relevance
UIKit questions test whether you know what the framework does for you and what it leaves to you. A candidate who can say "a cell is dequeued from a reuse pool, so I reset its content in prepareForReuse and guard against a stale async image" reads as someone who has debugged a real table. The strongest answers connect symptom to mechanism — a wrong-image flash to cell recycling, a janky scroll to an offscreen render pass, a "constraints unsatisfiable" log to an over-constrained axis, a crash to a UIKit call off the main thread — rather than reciting API names. Everything here rests on two rules worth stating up front: UIKit is main-thread-only, and almost nothing happens the instant you ask — it is scheduled for the next run-loop pass.