KVO
Key Value Observing
UIView
iOS Development
Swift

How can I do Key Value Observing and get a KVO callback on a UIView's frame?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

If your goal is "run code when a UIView changes size or position," KVO on frame is usually not the best tool. UIKit layout changes are better handled through layoutSubviews, viewDidLayoutSubviews, or constraint observation, because those mechanisms are designed for view geometry updates. KVO can sometimes be made to work for view properties, but it is fragile enough that the practical answer is usually to use layout callbacks instead.

Why KVO On frame Is Awkward

KVO is built around properties that are guaranteed to be KVO-compliant. UIKit geometry changes, especially under Auto Layout, are not something most iOS code should observe through KVO first. Even if you manage to observe a related property, you are often fighting the framework instead of using its normal layout lifecycle.

If the view's geometry changes because constraints were updated, the natural observation point is usually after layout has been resolved.

The Preferred Solution: Override layoutSubviews

If you own the view subclass, this is the cleanest approach.

swift
1import UIKit
2
3final class ObservedView: UIView {
4    override func layoutSubviews() {
5        super.layoutSubviews()
6        print("frame changed to \(frame)")
7    }
8}

This fires whenever UIKit lays out the view, which is exactly when geometry changes become meaningful.

From A View Controller: Use viewDidLayoutSubviews

If you do not own the view subclass and just need to react in the controller, use the controller's layout callback.

swift
1import UIKit
2
3final class DemoViewController: UIViewController {
4    @IBOutlet private weak var targetView: UIView!
5
6    override func viewDidLayoutSubviews() {
7        super.viewDidLayoutSubviews()
8        print("target frame is now \(targetView.frame)")
9    }
10}

This is much more idiomatic than bolting KVO onto view geometry from the outside.

If You Absolutely Need Observation-Like Behavior

Sometimes you want a callback-style mechanism without subclassing. A simple pattern is to expose a closure from a custom view and trigger it during layout.

swift
1import UIKit
2
3final class CallbackView: UIView {
4    var onFrameChange: ((CGRect) -> Void)?
5    private var lastFrame: CGRect = .zero
6
7    override func layoutSubviews() {
8        super.layoutSubviews()
9        if frame != lastFrame {
10            lastFrame = frame
11            onFrameChange?(frame)
12        }
13    }
14}

This gives you the same practical outcome as observation, but it is explicit, local, and UIKit-friendly.

What About Real KVO?

Modern Swift KVO works best with properties explicitly designed for it, usually on NSObject subclasses with observable properties. While some UIKit properties participate in KVO in some situations, building app logic around KVO for UIView.frame is not a pattern most iOS teams want to depend on.

If your real need is layout awareness, layout callbacks are the right abstraction. If your real need is model observation, use KVO or another state-observation mechanism on the model layer instead.

Auto Layout Changes Should Be Tracked At The Constraint Level

If the geometry depends on constraints and you specifically care about why the frame changed, constraint updates are often the better level of abstraction. You might observe constraint constants in your own code, or simply update dependent UI in the same place that changes the constraints.

That keeps cause and effect together instead of trying to infer the cause after the frame changes.

Common Pitfalls

  • Reaching for KVO because the problem sounds like observation, even though UIKit already provides layout lifecycle hooks.
  • Trying to observe frame from outside the view hierarchy and then fighting Auto Layout timing issues.
  • Using geometry callbacks before layout has settled, which gives misleading intermediate frames.
  • Building app logic around undocumented or fragile assumptions about UIKit property observation behavior.
  • Observing the symptom, frame, when the real source of truth is constraint state or explicit layout code.

Summary

  • If you need to react to a UIView frame change, prefer layout callbacks over KVO.
  • Use layoutSubviews in a custom view or viewDidLayoutSubviews in a controller.
  • If you want callback-style behavior, expose it from a custom view and trigger it during layout.
  • Treat real KVO as a better fit for model properties than for UIKit geometry.
  • In Auto Layout code, the cleanest fix is often to observe or control constraints rather than the resulting frame directly.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions