         change: [NSKeyValueChangeKey: Any]?,
         context _: UnsafeMutableRawPointer?
     ) {
-        guard _setupComplete, _updateLock == 0, _evaluating.isEmpty, let new = change?[.newKey] else {
+        guard _setupComplete, _updateLock == 0, _evaluating.isEmpty,
+            let view = _view, let new = change?[.newKey] else {
             return
         }
         switch new {
+        case is CGRect:
+            if !view.bounds.size.isNearlyEqual(to: _previousBounds.size) {
+                if root._setupComplete, root._updateLock == 0, root._evaluating.isEmpty {
+                    root.update()
+                    _previousBounds = view.bounds
+                }
+            }
         case let useAutoresizing as Bool:
             if useAutoresizing != change?[.oldKey] as? Bool {
                 update()

    private func _stopObservingFrame() {
        if _observingFrame {
            removeObserver(self, forKeyPath: "_view.translatesAutoresizingMaskIntoConstraints")
            _observingFrame = false
        }
    }

        }
        if !_observingFrame {
            addObserver(self, forKeyPath: "_view.translatesAutoresizingMaskIntoConstraints", options: [.new, .old], context: nil)
            addObserver(self, forKeyPath: "_view.frame", options: .new, context: nil)
            addObserver(self, forKeyPath: "_view.bounds", options: .new, context: nil)
            _observingFrame = true
        }
    }

    private var _previousBounds = CGRect.zero
    private var _previousSafeAreaInsets = UIEdgeInsets.zero
    private var _anyChildDependsOnContentOffset: Bool?
    fileprivate func updateLayout() {
        guard _setupComplete, _updateLock == 0, root._updateLock == 0, let view = _view else {
            return
        }
        if _shouldObserveInsets, !view._safeAreaInsets.isNearlyEqual(to: _previousSafeAreaInsets) {
            _previousSafeAreaInsets = view._safeAreaInsets
            update()
        } else if !view.bounds.size.isNearlyEqual(to: _previousBounds.size) {
            return // Don't update the frame inside layoutSubviews, or we'll create an infinite loop
        } else if view is UIScrollView, !view.bounds.origin.isNearlyEqual(to: _previousBounds.origin) {
            if _anyChildDependsOnContentOffset == nil {
                _anyChildDependsOnContentOffset = anyExpressionDependsOn([
                    "contentOffset", "contentOffset.x", "contentOffset.y",
