From e4e03d7361f0fc37ce7d7da9570139117b8aaae5 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Fri, 4 Oct 2024 18:19:41 +0100 Subject: [PATCH] [net9.0] Fix CV2 handler and uitests fixes (#25076) * [iOS] Make GridLayouts render header and footer * [ios] Fix grouping not working because of StructuredView * [tests] Add a small delay on changing orientation * Fix duplicated header --- .../Items2/CollectionViewHandler2.iOS.cs | 2 +- .../iOS/GroupableItemsViewController2.cs | 45 ++++++++++++++----- .../Handlers/Items2/iOS/LayoutFactory2.cs | 17 ++++--- .../iOS/StructuredItemsViewController2.cs | 11 +++-- .../Tests/Issues/Issue21967.cs | 5 ++- 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs b/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs index c27b8c7567de..f30f433e2426 100644 --- a/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs +++ b/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs @@ -173,7 +173,7 @@ protected override UICollectionViewLayout SelectLayout() if (itemsLayout is GridItemsLayout gridItemsLayout) { - return LayoutFactory2.CreateGrid(gridItemsLayout, groupInfo); + return LayoutFactory2.CreateGrid(gridItemsLayout, groupInfo, headerFooterInfo); } if (itemsLayout is LinearItemsLayout listItemsLayout) diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs index 9995dfe35710..6f23351071d5 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs @@ -58,6 +58,25 @@ protected override void RegisterViewTypes() RegisterSupplementaryViews(UICollectionElementKindSection.Footer); } + private protected override void RegisterSupplementaryViews(UICollectionElementKindSection kind) + { + base.RegisterSupplementaryViews(kind); + if (IsHorizontal) + { + CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalSupplementaryView2), + kind, HorizontalSupplementalView2ReuseId); + CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalDefaultSupplementalView2), + kind, HorizontalDefaultSupplementalView2ReuseId); + } + else + { + CollectionView.RegisterClassForSupplementaryView(typeof(VerticalSupplementaryView2), + kind, VerticalSupplementaryView2ReuseId); + CollectionView.RegisterClassForSupplementaryView(typeof(VerticalDefaultSupplementalView2), + kind, VerticalDefaultSupplementalView2ReuseId); + } + } + string DetermineViewReuseId(NSString elementKind) { return DetermineViewReuseId(elementKind == UICollectionElementKindSectionKey.Header @@ -68,12 +87,12 @@ string DetermineViewReuseId(NSString elementKind) public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath) { - var struc = base.GetViewForSupplementaryElement(collectionView, elementKind, indexPath); - if(struc != null) + var suplementaryViewFromStructuredView = base.GetViewForSupplementaryElement(collectionView, elementKind, indexPath); + if (suplementaryViewFromStructuredView is not null) { - return struc; + return suplementaryViewFromStructuredView; } - + var reuseId = DetermineViewReuseId(elementKind); var view = collectionView.DequeueReusableSupplementaryView(elementKind, reuseId, indexPath) as UICollectionReusableView; @@ -117,7 +136,7 @@ void UpdateTemplatedSupplementaryView(TemplatedCell2 cell, NSString elementKind, // } } - + string DetermineViewReuseId(DataTemplate template) { @@ -127,20 +146,26 @@ string DetermineViewReuseId(DataTemplate template) orientation = linearItemsLayout.Orientation; else if (this.ItemsView.ItemsLayout is GridItemsLayout gridItemsLayout) orientation = gridItemsLayout.Orientation; - + if (template == null) { // No template, fall back the the default supplemental views return orientation == ItemsLayoutOrientation.Horizontal - ? HorizontalDefaultSupplementalView2.ReuseId - : VerticalDefaultSupplementalView2.ReuseId; + ? HorizontalDefaultSupplementalView2ReuseId + : VerticalDefaultSupplementalView2ReuseId; } return orientation == ItemsLayoutOrientation.Horizontal - ? HorizontalSupplementaryView2.ReuseId - : VerticalSupplementaryView2.ReuseId; + ? HorizontalSupplementalView2ReuseId + : VerticalSupplementaryView2ReuseId; } + static NSString HorizontalDefaultSupplementalView2ReuseId = new NSString("Microsoft.Maui.Controls.HorizontalDefaultSupplementalGroupView2"); + static NSString VerticalDefaultSupplementalView2ReuseId = new NSString("Microsoft.Maui.Controls.VerticalDefaultSupplementaryGroupView2"); + static NSString HorizontalSupplementalView2ReuseId = new NSString("Microsoft.Maui.Controls.HorizontalSupplementalGroupView2"); + static NSString VerticalSupplementaryView2ReuseId = new NSString("Microsoft.Maui.Controls.VerticalSupplementaryGroupView2"); + + // internal CGSize GetReferenceSizeForHeader(UICollectionView collectionView, UICollectionViewLayout layout, nint section) // { // if (!_isGrouped) diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs index 30543d84cd43..5723cbebfe6d 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs @@ -14,10 +14,11 @@ public static UICollectionViewLayout CreateList(LinearItemsLayout linearItemsLay ? CreateVerticalList(linearItemsLayout, groupingInfo, headerFooterInfo) : CreateHorizontalList(linearItemsLayout, groupingInfo, headerFooterInfo); - public static UICollectionViewLayout CreateGrid(GridItemsLayout gridItemsLayout, LayoutGroupingInfo groupingInfo) + public static UICollectionViewLayout CreateGrid(GridItemsLayout gridItemsLayout, + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => gridItemsLayout.Orientation == ItemsLayoutOrientation.Vertical - ? CreateVerticalGrid(gridItemsLayout, groupingInfo) - : CreateHorizontalGrid(gridItemsLayout, groupingInfo); + ? CreateVerticalGrid(gridItemsLayout, groupingInfo, headerFooterInfo) + : CreateHorizontalGrid(gridItemsLayout, groupingInfo, headerFooterInfo); static NSCollectionLayoutBoundarySupplementaryItem[] CreateSupplementaryItems(LayoutGroupingInfo? groupingInfo, LayoutHeaderFooterInfo? layoutHeaderFooterInfo, UICollectionViewScrollDirection scrollDirection, NSCollectionLayoutDimension width, NSCollectionLayoutDimension height) @@ -140,7 +141,7 @@ static UICollectionViewLayout CreateListLayout(UICollectionViewScrollDirection s - static UICollectionViewLayout CreateGridLayout(UICollectionViewScrollDirection scrollDirection, LayoutGroupingInfo groupingInfo, LayoutSnapInfo snapInfo, NSCollectionLayoutDimension itemWidth, NSCollectionLayoutDimension itemHeight, NSCollectionLayoutDimension groupWidth, NSCollectionLayoutDimension groupHeight, double verticalItemSpacing, double horizontalItemSpacing, int columns) + static UICollectionViewLayout CreateGridLayout(UICollectionViewScrollDirection scrollDirection, LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo, LayoutSnapInfo snapInfo, NSCollectionLayoutDimension itemWidth, NSCollectionLayoutDimension itemHeight, NSCollectionLayoutDimension groupWidth, NSCollectionLayoutDimension groupHeight, double verticalItemSpacing, double horizontalItemSpacing, int columns) { var layoutConfiguration = new UICollectionViewCompositionalLayoutConfiguration(); layoutConfiguration.ScrollDirection = scrollDirection; @@ -179,7 +180,7 @@ static UICollectionViewLayout CreateGridLayout(UICollectionViewScrollDirection s section.BoundarySupplementaryItems = CreateSupplementaryItems( groupingInfo, - null, // No header/footer in grid + headerFooterInfo, scrollDirection, groupWidth, groupHeight); @@ -222,9 +223,10 @@ public static UICollectionViewLayout CreateHorizontalList(LinearItemsLayout line null); public static UICollectionViewLayout CreateVerticalGrid(GridItemsLayout gridItemsLayout, - LayoutGroupingInfo groupingInfo) + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => CreateGridLayout(UICollectionViewScrollDirection.Vertical, groupingInfo, + headerFooterInfo, new LayoutSnapInfo { SnapType = gridItemsLayout.SnapPointsType, SnapAligment = gridItemsLayout.SnapPointsAlignment }, // Width is the number of columns NSCollectionLayoutDimension.CreateFractionalWidth(1f / gridItemsLayout.Span), @@ -240,9 +242,10 @@ public static UICollectionViewLayout CreateVerticalGrid(GridItemsLayout gridItem public static UICollectionViewLayout CreateHorizontalGrid(GridItemsLayout gridItemsLayout, - LayoutGroupingInfo groupingInfo) + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => CreateGridLayout(UICollectionViewScrollDirection.Horizontal, groupingInfo, + headerFooterInfo, new LayoutSnapInfo { SnapType = gridItemsLayout.SnapPointsType, SnapAligment = gridItemsLayout.SnapPointsAlignment }, // Item width is estimated NSCollectionLayoutDimension.CreateEstimated(30f), diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs index 627c7d0518b8..0b3a63d88a52 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs @@ -48,9 +48,14 @@ protected override void Dispose(bool disposing) protected override bool IsHorizontal => (ItemsView?.ItemsLayout as ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal; - public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, - NSString elementKind, NSIndexPath indexPath) + public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath) { + // We don't have a header or footer, so we don't need to do anything + if(ItemsView.Header is null && ItemsView.Footer is null && ItemsView.HeaderTemplate is null && ItemsView.FooterTemplate is null) + { + return null; + } + var reuseId = DetermineViewReuseId(elementKind); var view = collectionView.DequeueReusableSupplementaryView(elementKind, reuseId, indexPath) as UICollectionReusableView; @@ -68,7 +73,7 @@ public override UICollectionReusableView GetViewForSupplementaryElement(UICollec return view; } - private protected void RegisterSupplementaryViews(UICollectionElementKindSection kind) + private protected virtual void RegisterSupplementaryViews(UICollectionElementKindSection kind) { if (IsHorizontal) { diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21967.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21967.cs index ee208b9f3a92..2980bfbb1fde 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21967.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21967.cs @@ -40,17 +40,20 @@ public void CollectionViewFirstItemCorrectlySetsTheMeasure() [Category(UITestCategories.CollectionView)] [FailsOnMac("This test is failing, likely due to product issue")] [FailsOnWindows("This test is failing, likely due to product issue")] - public void CollectionViewWorksWhenRotatingDevice() + public async Task CollectionViewWorksWhenRotatingDevice() { try { App.WaitForElement("FullSize"); App.Tap("FullSize"); App.SetOrientationPortrait(); + await Task.Delay(100); var itemSizePortrait = App.WaitForElement("Item1").GetRect(); App.SetOrientationLandscape(); + await Task.Delay(100); var itemSizeLandscape = App.WaitForElement("Item1").GetRect(); App.SetOrientationPortrait(); + await Task.Delay(100); var itemSizePortrait2 = App.WaitForElement("Item1").GetRect(); ClassicAssert.Greater(itemSizeLandscape.Width, itemSizePortrait.Width);