diff --git a/src/Core/src/Platform/iOS/MauiView.cs b/src/Core/src/Platform/iOS/MauiView.cs index 68439a781489..4518f5538daf 100644 --- a/src/Core/src/Platform/iOS/MauiView.cs +++ b/src/Core/src/Platform/iOS/MauiView.cs @@ -144,6 +144,10 @@ static UIEdgeInsets ComputeCellSafeAreaInsets(UIView cell, ISafeAreaView2 safeVi // Null means not yet determined. Invalidated when view hierarchy changes. bool? _parentHandlesSafeArea; + // Indicates whether the measure invalidation has already been propagated + // to ancestors during this main loop. + bool _measureInvalidatedPropagated; + // Keyboard tracking CGRect _keyboardFrame = CGRect.Empty; bool _isKeyboardShowing; @@ -621,6 +625,10 @@ void CrossPlatformArrange(CGRect bounds) /// The size that fits within the constraints public override CGSize SizeThatFits(CGSize size) { + // Invalidations shouldn't happen during measure pass, + // but we need to support that in case it happens. + _measureInvalidatedPropagated = false; + if (_crossPlatformLayoutReference == null) { return base.SizeThatFits(size); @@ -653,6 +661,9 @@ public override void LayoutSubviews() { base.LayoutSubviews(); + // Allow measure invalidations during layout pass + _measureInvalidatedPropagated = false; + if (_crossPlatformLayoutReference == null) { return; @@ -799,6 +810,12 @@ bool IPlatformMeasureInvalidationController.InvalidateMeasure(bool isPropagating // If we're not propagating, then this view is the one triggering the invalidation // and one possible cause is that constraints have changed, so we have to propagate the invalidation. + if (_measureInvalidatedPropagated) + { + return false; + } + + _measureInvalidatedPropagated = true; return true; }