← 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 2

Bounds, frame, and the iOS coordinate system

Explain how bounds and frame differ, what coordinate system each uses, and how center fits in. Why does this matter when positioning subviews or applying transforms?

Follow-ups

  • What happens to frame when you apply a rotation transform?
  • Why does UIScrollView change bounds.origin?

Answer outline

frame: A rectangle in the superview’s coordinate space. Its origin is where this view’s top-left of its axis-aligned box sits in the parent. It answers: where is this view in its parent?

bounds: A rectangle in this view’s own (local) coordinate space. bounds.size is the extent used for drawing, local hit testing, and subview layout. bounds.origin is often (0, 0) for a plain UIView, but UIScrollView updates bounds.origin (via contentOffset) to scroll content while the view’s frame in the superview can stay fixed.

center: The view’s position in the superview’s coordinate system — together with bounds it determines frame. UIView applies transform around the center; after rotation or scale, frame is the axis-aligned bounding box in the parent, while bounds usually still describes untransformed content size in local space.

Subviews: A subview’s frame is always in its superview’s space. Confusing parent frame space with child bounds space is a common source of misplaced controls and wrong touch maps.

frame lives in the superview's coordinate space; bounds lives in the view's own space. After a transform, frame is unreliable — use center + bounds instead.

Principles

  • Frame ↔ parent’s coordinates.
  • bounds ↔ this view’s local coordinates (content + subviews).
  • After transform, frame.size need not match bounds.size—the bounding box grows to fit the rotated corners in the parent.

bounds describes local size (and scroll offset); frame describes placement in the superview.

Two rectangles, two spaces
print(view.bounds) // local — size + content offset (e.g. scroll)
print(view.frame)  // in superview — position + size

Scrolling moves bounds.origin so different content appears under the same frame in the parent.

Scroll view (idea)
// contentOffset ↔ bounds.origin — frame may not move

Follow-up angles

  • CALayer: analogous frame / bounds / position; anchorPoint pairs with position for transforms.