Skip to content

Commit ec246ac

Browse files
committed
Bring back iOS SetNeedsLayout propagation via inheritance
1 parent 90e36c5 commit ec246ac

File tree

15 files changed

+132
-65
lines changed

15 files changed

+132
-65
lines changed

src/Controls/src/Core/Compatibility/Handlers/iOS/VisualElementRenderer.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,15 @@ void IPlatformMeasureInvalidationController.InvalidateAncestorsMeasuresWhenMoved
9999
_invalidateParentWhenMovedToWindow = true;
100100
}
101101

102-
void IPlatformMeasureInvalidationController.InvalidateMeasure(bool isPropagating) => SetNeedsLayout();
102+
public override void SetNeedsLayout()
103+
{
104+
base.SetNeedsLayout();
105+
106+
if (IPlatformMeasureInvalidationController.IsInvalidating)
107+
{
108+
this.InvalidateParentMeasure();
109+
}
110+
}
103111

104112
public override void MovedToWindow()
105113
{

src/Controls/src/Core/Handlers/Items/iOS/ItemsViewCell.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public abstract class ItemsViewCell : UICollectionViewCell
1414
protected ItemsViewCell(CGRect frame) : base(frame)
1515
{
1616
ContentView.BackgroundColor = UIColor.Clear;
17+
ContentView.Tag = IPlatformMeasureInvalidationController.PropagationProxyTag;
1718

1819
var selectedBackgroundView = new UIView
1920
{

src/Controls/src/Core/Handlers/Items/iOS/MauiCollectionView.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ void IPlatformMeasureInvalidationController.InvalidateAncestorsMeasuresWhenMoved
2525
_invalidateParentWhenMovedToWindow = true;
2626
}
2727

28-
void IPlatformMeasureInvalidationController.InvalidateMeasure(bool isPropagating)
28+
public override void SetNeedsLayout()
2929
{
30-
if (!isPropagating)
30+
base.SetNeedsLayout();
31+
32+
if (IPlatformMeasureInvalidationController.IsInvalidatingSelf)
3133
{
32-
SetNeedsLayout();
34+
this.InvalidateParentMeasure();
3335
}
3436
}
3537

src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewCell2.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public abstract class ItemsViewCell2 : UICollectionViewCell
1414
protected ItemsViewCell2(CGRect frame) : base(frame)
1515
{
1616
ContentView.BackgroundColor = UIColor.Clear;
17+
ContentView.Tag = IPlatformMeasureInvalidationController.PropagationProxyTag;
1718

1819
var selectedBackgroundView = new UIView
1920
{

src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22
Microsoft.Maui.Controls.StyleableElement.Style.get -> Microsoft.Maui.Controls.Style?
3+
override Microsoft.Maui.Controls.Handlers.Compatibility.VisualElementRenderer<TElement>.SetNeedsLayout() -> void
34
override Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size
45
~abstract Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.CreateController(TItemsView newElement, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2<TItemsView>
56
~abstract Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.SelectLayout() -> UIKit.UICollectionViewLayout

src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22
Microsoft.Maui.Controls.StyleableElement.Style.get -> Microsoft.Maui.Controls.Style?
3+
override Microsoft.Maui.Controls.Handlers.Compatibility.VisualElementRenderer<TElement>.SetNeedsLayout() -> void
34
override Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size
45
~abstract Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.CreateController(TItemsView newElement, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2<TItemsView>
56
~abstract Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2<TItemsView>.SelectLayout() -> UIKit.UICollectionViewLayout

src/Core/src/Handlers/Page/PageHandler.iOS.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public override void SetVirtualView(IView view)
2525
{
2626
base.SetVirtualView(view);
2727

28-
// Ensure we tag the ContentView as a Page so that InvalidateAncestorsMeasures can stop propagation here
29-
PlatformView.IsPage = true;
28+
// Ensure we mark this as root view so the invalidation propagation stops here
29+
PlatformView.IsRootView = true;
3030
}
3131

3232
public static void MapBackground(IPageHandler handler, IContentView page)

src/Core/src/Platform/iOS/ContentView.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ public class ContentView : MauiView
1616
// verify we're using the correct subview for masking (and any other purposes)
1717
internal const nint ContentTag = 0x63D2A0;
1818

19-
internal bool IsPage { get; set; }
20-
2119
public ContentView()
2220
{
2321
if (OperatingSystem.IsIOSVersionAtLeast(13) || OperatingSystem.IsMacCatalystVersionAtLeast(13, 1))
Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,41 @@
1+
using UIKit;
2+
13
namespace Microsoft.Maui.Platform;
24

35
internal interface IPlatformMeasureInvalidationController
46
{
7+
/// <summary>
8+
/// Marks a UIView with this tag when it's not possible to use inheritance to override SetNeedsLayout.
9+
/// When this tag is found, the invalidation is automatically propagated to the parent.
10+
/// </summary>
11+
const nint PropagationProxyTag = 0x845fff;
12+
13+
static int _invalidationDepth;
14+
15+
/// <summary>
16+
/// Gets whether we're currently running an invalidation pass.
17+
/// </summary>
18+
public static bool IsInvalidating => _invalidationDepth > 0;
19+
20+
/// <summary>
21+
/// Gets whether the current invalidation pass is invalidating the view which triggered the invalidation.
22+
/// </summary>
23+
public static bool IsInvalidatingSelf => _invalidationDepth == 1;
24+
25+
/// <summary>
26+
/// Gets whether the current invalidation pass is invalidating the ancestors of the view which triggered the invalidation.
27+
/// </summary>
28+
public static bool IsPropagatingInvalidation => _invalidationDepth > 1;
29+
30+
public static void BeginInvalidation() => _invalidationDepth = 0;
31+
public static void BeginAncestorsInvalidation() => _invalidationDepth = 1;
32+
public static void EndInvalidation() => _invalidationDepth = 0;
33+
34+
public static void SetNeedsLayout(UIView view)
35+
{
36+
++_invalidationDepth;
37+
view.SetNeedsLayout();
38+
}
39+
540
void InvalidateAncestorsMeasuresWhenMovedToWindow();
6-
void InvalidateMeasure(bool isPropagating = false);
741
}

src/Core/src/Platform/iOS/MauiScrollView.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,19 @@ void IPlatformMeasureInvalidationController.InvalidateAncestorsMeasuresWhenMoved
8787
_invalidateParentWhenMovedToWindow = true;
8888
}
8989

90-
void IPlatformMeasureInvalidationController.InvalidateMeasure(bool isPropagating)
90+
public override void SetNeedsLayout()
9191
{
92-
SetNeedsLayout();
93-
InvalidateConstraintsCache();
92+
base.SetNeedsLayout();
93+
94+
if (IPlatformMeasureInvalidationController.IsInvalidating)
95+
{
96+
InvalidateConstraintsCache();
97+
}
98+
99+
if (IPlatformMeasureInvalidationController.IsInvalidatingSelf)
100+
{
101+
this.InvalidateParentMeasure();
102+
}
94103
}
95104

96105
bool IsMeasureValid(double widthConstraint, double heightConstraint)

0 commit comments

Comments
 (0)