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

            }
            if _anyChildDependsOnContentOffset == true {
                children.forEach { $0.update() }
                _previousBounds = _view!.bounds
                return
            }
        }
        _previousBounds = bounds
    }

    public override func observeValue(

        }
        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",
