diff --git a/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs b/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs index 1ac2957dcd..d9255188a7 100644 --- a/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs +++ b/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs @@ -1,11 +1,36 @@ #nullable disable using System; using Foundation; +using Microsoft.Maui.Controls.Handlers.Items; using Microsoft.Maui.Graphics; using UIKit; namespace Microsoft.Maui.Controls.Handlers.Items2 { + public partial class CarouselViewHandler2 + { + + public CarouselViewHandler2() : base(Mapper) + { + + + } + public CarouselViewHandler2(PropertyMapper mapper = null) : base(mapper ?? Mapper) + { + + } + + public static PropertyMapper Mapper = new(ItemsViewMapper) + { + + [Controls.CarouselView.IsSwipeEnabledProperty.PropertyName] = MapIsSwipeEnabled, + [Controls.CarouselView.PeekAreaInsetsProperty.PropertyName] = MapPeekAreaInsets, + [Controls.CarouselView.IsBounceEnabledProperty.PropertyName] = MapIsBounceEnabled, + [Controls.CarouselView.PositionProperty.PropertyName] = MapPosition, + [Controls.CarouselView.CurrentItemProperty.PropertyName] = MapCurrentItem + }; + } + public partial class CarouselViewHandler2 : ItemsViewHandler2 { protected override CarouselViewController2 CreateController(CarouselView newElement, UICollectionViewLayout layout) @@ -111,23 +136,26 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 protected override void ScrollToRequested(object sender, ScrollToRequestEventArgs args) { - // if (VirtualView?.Loop == true) - // { - // var goToIndexPath = (Controller as CarouselViewController2).GetScrollToIndexPath(args.Index); + if (VirtualView?.Loop == true) + { + var goToIndexPath = (Controller as CarouselViewController2).GetScrollToIndexPath(args.Index); - // if (!IsIndexPathValid(goToIndexPath)) - // { - // return; - // } + if (!IsIndexPathValid(goToIndexPath)) + { + return; + } - // Controller.CollectionView.ScrollToItem(goToIndexPath, - // args.ScrollToPosition.ToCollectionViewScrollPosition( UICollectionViewScrollDirection.Vertical), // TODO: Fix _layout.ScrollDirection), - // args.IsAnimated); - // } - // else - // { - base.ScrollToRequested(sender, args); - // } + bool IsHorizontal = VirtualView.ItemsLayout.Orientation == ItemsLayoutOrientation.Horizontal; + UICollectionViewScrollDirection scrollDirection = IsHorizontal ? UICollectionViewScrollDirection.Horizontal : UICollectionViewScrollDirection.Vertical; + + Controller.CollectionView.ScrollToItem(goToIndexPath, + args.ScrollToPosition.ToCollectionViewScrollPosition(scrollDirection), // TODO: Fix _layout.ScrollDirection), + args.IsAnimated); + } + else + { + base.ScrollToRequested(sender, args); + } } public static void MapIsSwipeEnabled(CarouselViewHandler2 handler, CarouselView carouselView) diff --git a/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs b/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs index 6e451f6188..c27b8c7567 100644 --- a/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs +++ b/src/Controls/src/Core/Handlers/Items2/CollectionViewHandler2.iOS.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; using System.Collections.Generic; using System.Text; using Foundation; @@ -8,6 +9,16 @@ using UIKit; namespace Microsoft.Maui.Controls.Handlers.Items2 { + internal class LayoutHeaderFooterInfo + { + public IView FooterView { get; set; } + public IView HeaderView { get; set; } + public DataTemplate FooterTemplate { get; set; } + public DataTemplate HeaderTemplate { get; set; } + public bool HasHeader { get; set; } + public bool HasFooter { get; set; } + } + internal class LayoutGroupingInfo { public bool IsGrouped { get; set; } @@ -21,6 +32,33 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 public SnapPointsType SnapType { get; set; } } + public partial class CollectionViewHandler2 + { + + public CollectionViewHandler2() : base(Mapper) + { + + + } + public CollectionViewHandler2(PropertyMapper mapper = null) : base(mapper ?? Mapper) + { + + } + + public static PropertyMapper Mapper = new(ItemsViewMapper) + { + [ReorderableItemsView.CanReorderItemsProperty.PropertyName] = MapCanReorderItems, + [GroupableItemsView.IsGroupedProperty.PropertyName] = MapIsGrouped, + [SelectableItemsView.SelectedItemProperty.PropertyName] = MapSelectedItem, + [SelectableItemsView.SelectedItemsProperty.PropertyName] = MapSelectedItems, + [SelectableItemsView.SelectionModeProperty.PropertyName] = MapSelectionMode, + [StructuredItemsView.HeaderTemplateProperty.PropertyName] = MapHeaderTemplate, + [StructuredItemsView.FooterTemplateProperty.PropertyName] = MapFooterTemplate, + [StructuredItemsView.HeaderProperty.PropertyName] = MapHeaderTemplate, + [StructuredItemsView.FooterProperty.PropertyName] = MapFooterTemplate, + }; + } + public partial class CollectionViewHandler2 : ItemsViewHandler2 { // Reorderable @@ -32,7 +70,6 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 (handler.Controller as ReorderableItemsViewController2)?.UpdateCanReorderItems(); } - // Groupable protected override void ScrollToRequested(object sender, ScrollToRequestEventArgs args) { @@ -90,6 +127,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // Structured protected override UICollectionViewLayout SelectLayout() { + var headerFooterInfo = new LayoutHeaderFooterInfo(); var groupInfo = new LayoutGroupingInfo(); if (ItemsView is GroupableItemsView groupableItemsView && groupableItemsView.IsGrouped) @@ -99,6 +137,22 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 groupInfo.HasFooter = groupableItemsView.GroupFooterTemplate is not null; } + if (ItemsView is StructuredItemsView structuredItemsView) + { + headerFooterInfo.HeaderTemplate = structuredItemsView.HeaderTemplate; + headerFooterInfo.FooterTemplate = structuredItemsView.FooterTemplate; + if (structuredItemsView.Header is View headerView) + { + headerFooterInfo.HeaderView = headerView; + } + if (structuredItemsView.Footer is View footerView) + { + headerFooterInfo.FooterView = footerView; + } + headerFooterInfo.HasHeader = structuredItemsView.Header is not null; + headerFooterInfo.HasFooter = structuredItemsView.Footer is not null; + } + var itemSizingStrategy = ItemsView.ItemSizingStrategy; var itemsLayout = ItemsView.ItemsLayout; @@ -124,21 +178,23 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 if (itemsLayout is LinearItemsLayout listItemsLayout) { - return LayoutFactory2.CreateList(listItemsLayout, groupInfo); + return LayoutFactory2.CreateList(listItemsLayout, groupInfo, headerFooterInfo); } // Fall back to vertical list - return LayoutFactory2.CreateList(new LinearItemsLayout(ItemsLayoutOrientation.Vertical), groupInfo); + return LayoutFactory2.CreateList(new LinearItemsLayout(ItemsLayoutOrientation.Vertical), groupInfo, headerFooterInfo); } public static void MapHeaderTemplate(CollectionViewHandler2 handler, StructuredItemsView itemsView) { - (handler.Controller as StructuredItemsViewController2)?.UpdateHeaderView(); + handler.UpdateLayout(); + // (handler.Controller as StructuredItemsViewController2)?.UpdateHeaderView(); } public static void MapFooterTemplate(CollectionViewHandler2 handler, StructuredItemsView itemsView) { - (handler.Controller as StructuredItemsViewController2)?.UpdateFooterView(); + handler.UpdateLayout(); + //(handler.Controller as StructuredItemsViewController2)?.UpdateFooterView(); } public static void MapItemsLayout(CollectionViewHandler2 handler, StructuredItemsView itemsView) diff --git a/src/Controls/src/Core/Handlers/Items2/ItemsViewHandler2.iOS.cs b/src/Controls/src/Core/Handlers/Items2/ItemsViewHandler2.iOS.cs index afd1a289fc..935aad2d55 100644 --- a/src/Controls/src/Core/Handlers/Items2/ItemsViewHandler2.iOS.cs +++ b/src/Controls/src/Core/Handlers/Items2/ItemsViewHandler2.iOS.cs @@ -64,7 +64,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 protected abstract UICollectionViewLayout SelectLayout(); protected abstract ItemsViewController2 CreateController(TItemsView newElement, UICollectionViewLayout layout); - + protected override UIView CreatePlatformView() => Controller?.View; public static void MapItemsSource(ItemsViewHandler2 handler, ItemsView itemsView) @@ -176,9 +176,11 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // public override Size GetDesiredSize(double widthConstraint, double heightConstraint) // { // var size = base.GetDesiredSize(widthConstraint, heightConstraint); - // + // var potentialContentSize = Controller.GetSize(); - // + + + // System.Diagnostics.Debug.WriteLine($"potentialContentSize: {potentialContentSize}"); // // If contentSize comes back null, it means none of the content has been realized yet; // // we need to return the expansive size the collection view wants by default to get // // it to start measuring its content @@ -186,19 +188,19 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // { // return size; // } - // + // var contentSize = potentialContentSize.Value; - // + // // If contentSize does have a value, our target size is the smaller of it and the constraints - // + // size.Width = contentSize.Width <= widthConstraint ? contentSize.Width : widthConstraint; // size.Height = contentSize.Height <= heightConstraint ? contentSize.Height : heightConstraint; - // + // var virtualView = this.VirtualView as IView; - // + // size.Width = ViewHandlerExtensions.ResolveConstraints(size.Width, virtualView.Width, virtualView.MinimumWidth, virtualView.MaximumWidth); // size.Height = ViewHandlerExtensions.ResolveConstraints(size.Height, virtualView.Height, virtualView.MinimumHeight, virtualView.MaximumHeight); - // + // return size; // } } diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/CarouselTemplatedCell2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/CarouselTemplatedCell2.cs deleted file mode 100644 index 88bc9437e0..0000000000 --- a/src/Controls/src/Core/Handlers/Items2/iOS/CarouselTemplatedCell2.cs +++ /dev/null @@ -1,48 +0,0 @@ -#nullable disable -using System; -using CoreGraphics; -using Foundation; -using Microsoft.Maui.Graphics; -using ObjCRuntime; -using UIKit; - -namespace Microsoft.Maui.Controls.Handlers.Items2 -{ - public class CarouselTemplatedCell2 : TemplatedCell2 - { - public new static NSString ReuseId = new NSString("Microsoft.Maui.Controls.CarouselTemplatedCell2"); - //CGSize _constraint; - - [Export("initWithFrame:")] - [Microsoft.Maui.Controls.Internals.Preserve(Conditional = true)] - protected CarouselTemplatedCell2(CGRect frame) : base(frame) - { - } - - // public override void ConstrainTo(nfloat constant) - // { - // } - // - // public override void ConstrainTo(CGSize constraint) - // { - // ClearConstraints(); - // - // _constraint = constraint; - // } - - // public override CGSize Measure() - // { - // return new CGSize(_constraint.Width, _constraint.Height); - // } - // - // protected override (bool, Size) NeedsContentSizeUpdate(Size currentSize) - // { - // return (false, Size.Zero); - // } - // - // protected override bool AttributesConsistentWithConstrainedDimension(UICollectionViewLayoutAttributes attributes) - // { - // return false; - // } - } -} diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cs index 8f6adbd774..0560db50e7 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cs @@ -124,15 +124,9 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 return base.DetermineCellReuseId(itemIndex); } - protected override void RegisterViewTypes() - { - CollectionView.RegisterClassForCell(typeof(CarouselTemplatedCell2), CarouselTemplatedCell2.ReuseId); - base.RegisterViewTypes(); - } - protected override Items.IItemsViewSource CreateItemsViewSource() { - var itemsSource = Items.ItemsSourceFactory.CreateForCarouselView(ItemsView.ItemsSource, this, ItemsView.Loop); + var itemsSource = Items2.ItemsSourceFactory2.CreateForCarouselView(ItemsView.ItemsSource, this, ItemsView.Loop); _carouselViewLoopManager?.SetItemsSource(itemsSource); SubscribeCollectionItemsSourceChanged(itemsSource); return itemsSource; @@ -142,6 +136,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { base.AttachingToWindow(); Setup(ItemsView); + UpdateInitialPosition(); } private protected override void DetachingFromWindow() @@ -155,6 +150,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 void TearDown(CarouselView carouselView) { _oldViews = null; + InitialPositionSet = false; //carouselView.Scrolled -= CarouselViewScrolled; diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs index 32ef56d730..9995dfe357 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cs @@ -58,21 +58,22 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 RegisterSupplementaryViews(UICollectionElementKindSection.Footer); } - void RegisterSupplementaryViews(UICollectionElementKindSection kind) + string DetermineViewReuseId(NSString elementKind) { - CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalSupplementaryView2), - kind, HorizontalSupplementaryView2.ReuseId); - CollectionView.RegisterClassForSupplementaryView(typeof(VerticalSupplementaryView2), - kind, VerticalSupplementaryView2.ReuseId); - CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalDefaultSupplementalView2), - kind, HorizontalDefaultSupplementalView2.ReuseId); - CollectionView.RegisterClassForSupplementaryView(typeof(VerticalDefaultSupplementalView2), - kind, VerticalDefaultSupplementalView2.ReuseId); + return DetermineViewReuseId(elementKind == UICollectionElementKindSectionKey.Header + ? ItemsView.GroupHeaderTemplate + : ItemsView.GroupFooterTemplate); } public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath) { + var struc = base.GetViewForSupplementaryElement(collectionView, elementKind, indexPath); + if(struc != null) + { + return struc; + } + var reuseId = DetermineViewReuseId(elementKind); var view = collectionView.DequeueReusableSupplementaryView(elementKind, reuseId, indexPath) as UICollectionReusableView; @@ -116,12 +117,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // } } - string DetermineViewReuseId(NSString elementKind) - { - return DetermineViewReuseId(elementKind == UICollectionElementKindSectionKey.Header - ? ItemsView.GroupHeaderTemplate - : ItemsView.GroupFooterTemplate); - } + string DetermineViewReuseId(DataTemplate template) { diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/ItemsSourceFactory2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/ItemsSourceFactory2.cs new file mode 100644 index 0000000000..c4071d41ce --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items2/iOS/ItemsSourceFactory2.cs @@ -0,0 +1,29 @@ +#nullable disable +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using Microsoft.Maui.Controls.Handlers.Items; +using UIKit; + + +namespace Microsoft.Maui.Controls.Handlers.Items2; + +internal static class ItemsSourceFactory2 +{ + public static ILoopItemsViewSource CreateForCarouselView(IEnumerable itemsSource, UICollectionViewController collectionViewController, bool loop) + { + if (itemsSource == null) + { + return new EmptySource(); + } + + return itemsSource switch + { + IList _ when itemsSource is INotifyCollectionChanged => new LoopObservableItemsSource2(itemsSource as IList, collectionViewController, loop), + IEnumerable _ when itemsSource is INotifyCollectionChanged => new LoopObservableItemsSource2(itemsSource as IEnumerable, collectionViewController, loop), + IEnumerable generic => new LoopListSource2(generic, loop), + _ => new LoopListSource(itemsSource, loop), + }; + } + +} diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cs index 5fe3fa6c89..ac505b7cab 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; +using System.Linq; using CoreGraphics; using Foundation; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Graphics; +using PassKit; using UIKit; namespace Microsoft.Maui.Controls.Handlers.Items2 @@ -32,7 +34,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 bool _isEmpty = true; bool _emptyViewDisplayed; bool _disposed; - + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIView _emptyUIView; VisualElement _emptyViewFormsElement; @@ -43,12 +45,11 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 protected UICollectionViewScrollDirection ScrollDirection { get; private set; } = UICollectionViewScrollDirection.Vertical; - + protected ItemsViewController2(TItemsView itemsView, UICollectionViewLayout layout) : base(layout) { _itemsView = new(itemsView); ItemsViewLayout = layout; - } public void UpdateLayout(UICollectionViewLayout newLayout) @@ -104,20 +105,21 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { var cell = collectionView.DequeueReusableCell(DetermineCellReuseId(indexPath), indexPath) as UICollectionViewCell; + // We need to get the index path that is adjusted for the item source + // Some ItemsView like CarouselView have a loop feature that will make the index path different from the item source + var indexpathAdjusted = GetAdjustedIndexPathForItemSource(indexPath); + if (cell is TemplatedCell2 TemplatedCell2) { - //var virtualView = ItemsView.ItemTemplate.CreateContent() as View; TemplatedCell2.ScrollDirection = ScrollDirection; - //var nativeView = virtualView!.ToPlatform(ItemsView.FindMauiContext()!); - var indexpathAdjusted = GetAdjustedIndexPathForItemSource(indexPath); - TemplatedCell2.Bind(ItemsView.ItemTemplate, ItemsSource[indexpathAdjusted], ItemsView); + TemplatedCell2.Bind(ItemsView.ItemTemplate, ItemsSource[indexpathAdjusted], ItemsView); } else if (cell is DefaultCell2 DefaultCell2) { - DefaultCell2.Label.Text = ItemsSource[indexPath].ToString(); + DefaultCell2.Label.Text = ItemsSource[indexpathAdjusted].ToString(); } - + return cell; } @@ -133,7 +135,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 var wasEmpty = _isEmpty; _isEmpty = ItemsSource.ItemCount == 0; - + if (wasEmpty != _isEmpty) { UpdateEmptyViewVisibility(_isEmpty); @@ -183,15 +185,13 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 collectionView.SetCustomDelegate(this); CollectionView = collectionView; } - + public override void ViewWillLayoutSubviews() { base.ViewWillLayoutSubviews(); LayoutEmptyView(); } - - void Items.MauiCollectionView.ICustomMauiCollectionViewDelegate.MovedToWindow(UIView view) { if (CollectionView?.Window != null) @@ -254,7 +254,8 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // } // _previousContentSize = contentSize.Value; // } - + + const int HeaderTag = 111; // internal Size? GetSize() // { @@ -262,8 +263,15 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 // { // return _emptyUIView.Frame.Size.ToSize(); // } - // - // return CollectionView.CollectionViewLayout.CollectionViewContentSize.ToSize(); + + // nfloat headerHeight = 0; + // var headerView = CollectionView.ViewWithTag(HeaderTag); + + // if (headerView != null) + // headerHeight = headerView.Frame.Height; + + // var sizeColl = CollectionView.CollectionViewLayout.CollectionViewContentSize; + // return sizeColl.ToSize(); // } // void ConstrainItemsToBounds() @@ -281,7 +289,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 } _initialized = true; - + Delegator = CreateDelegator(); CollectionView.Delegate = Delegator; @@ -328,8 +336,8 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 CheckForEmptySource(); return ItemsSource.GroupCount; } - - + + public virtual NSIndexPath GetIndexForItem(object item) { return ItemsSource.GetIndexForItem(item); @@ -340,58 +348,14 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 return ItemsSource[index]; } - [UnconditionalSuppressMessage("Memory", "MEM0003", Justification = "Proven safe in test: CollectionViewTests.ItemsSourceDoesNotLeak")] - void CellContentSizeChanged(object sender, EventArgs e) - { - if (_disposed) - return; - - if (!(sender is TemplatedCell2 cell)) - { - return; - } - - var visibleCells = CollectionView.VisibleCells; - - for (int n = 0; n < visibleCells.Length; n++) - { - if (cell == visibleCells[n]) - { - ItemsViewLayout?.InvalidateLayout(); - return; - } - } - } - - // [UnconditionalSuppressMessage("Memory", "MEM0003", Justification = "Proven safe in test: CollectionViewTests.ItemsSourceDoesNotLeak")] - // void CellLayoutAttributesChanged(object sender, LayoutAttributesChangedEventArgs2 args) - // { - // CacheCellAttributes(args.NewAttributes.IndexPath, args.NewAttributes.Size); - // } - // - // protected virtual void CacheCellAttributes(NSIndexPath indexPath, CGSize size) - // { - // if (!ItemsSource.IsIndexPathValid(indexPath)) - // { - // // The upate might be coming from a cell that's being removed; don't cache it. - // return; - // } - // - // var item = ItemsSource[indexPath]; - // if (item != null) - // { - // ItemsViewLayout.CacheCellSize(item, size); - // } - // } - protected virtual string DetermineCellReuseId(NSIndexPath indexPath) { if (ItemsView.ItemTemplate != null) { var item = ItemsSource[indexPath]; - + var dataTemplate = ItemsView.ItemTemplate.SelectDataTemplate(item, ItemsView); - + var cellType = typeof(TemplatedCell2); var orientation = ScrollDirection == UICollectionViewScrollDirection.Horizontal ? "Horizontal" : "Vertical"; @@ -410,21 +374,6 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 return ScrollDirection == UICollectionViewScrollDirection.Horizontal ? HorizontalDefaultCell2.ReuseId : VerticalDefaultCell2.ReuseId; } - //[Obsolete("Use DetermineCellReuseId(NSIndexPath indexPath) instead.")] - //protected virtual string DetermineCellReuseId() - //{ - // if (ItemsView.ItemTemplate != null) - // { - // return ScrollDirection == UICollectionViewScrollDirection.Horizontal - // ? HorizontalCell2.ReuseId - // : VerticalCell2.ReuseId; - // } - - // return ScrollDirection == UICollectionViewScrollDirection.Horizontal - // ? HorizontalDefaultCell2.ReuseId - // : VerticalDefaultCell2.ReuseId; - //} - protected virtual void RegisterViewTypes() { CollectionView.RegisterClassForCell(typeof(HorizontalDefaultCell2), HorizontalDefaultCell2.ReuseId); @@ -441,7 +390,6 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 CollectionView.Frame.Width, CollectionView.Frame.Height); } - internal void UpdateView(object view, DataTemplate viewTemplate, ref UIView uiView, ref VisualElement formsElement) { @@ -452,11 +400,11 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { //Platform.GetRenderer(formsElement)?.DisposeRendererAndChildren(); } - - + + uiView?.Dispose(); uiView = null; - + formsElement = null; } else @@ -597,7 +545,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 if (_emptyViewFormsElement != null && ((IElementController)ItemsView).LogicalChildren.IndexOf(_emptyViewFormsElement) != -1) _emptyViewFormsElement.Layout(frame.ToRectangle()); } - + internal protected virtual void UpdateVisibility() { if (ItemsView.IsVisible) diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs index 1d260f0d3f..30543d84cd 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cs @@ -9,20 +9,20 @@ namespace Microsoft.Maui.Controls.Handlers.Items2; internal static class LayoutFactory2 { public static UICollectionViewLayout CreateList(LinearItemsLayout linearItemsLayout, - LayoutGroupingInfo groupingInfo) + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => linearItemsLayout.Orientation == ItemsLayoutOrientation.Vertical - ? CreateVerticalList(linearItemsLayout, groupingInfo) - : CreateHorizontalList(linearItemsLayout, groupingInfo); + ? CreateVerticalList(linearItemsLayout, groupingInfo, headerFooterInfo) + : CreateHorizontalList(linearItemsLayout, groupingInfo, headerFooterInfo); public static UICollectionViewLayout CreateGrid(GridItemsLayout gridItemsLayout, LayoutGroupingInfo groupingInfo) => gridItemsLayout.Orientation == ItemsLayoutOrientation.Vertical ? CreateVerticalGrid(gridItemsLayout, groupingInfo) : CreateHorizontalGrid(gridItemsLayout, groupingInfo); - static NSCollectionLayoutBoundarySupplementaryItem[] CreateSupplementaryItems(LayoutGroupingInfo groupingInfo, + static NSCollectionLayoutBoundarySupplementaryItem[] CreateSupplementaryItems(LayoutGroupingInfo? groupingInfo, LayoutHeaderFooterInfo? layoutHeaderFooterInfo, UICollectionViewScrollDirection scrollDirection, NSCollectionLayoutDimension width, NSCollectionLayoutDimension height) { - if (groupingInfo.IsGrouped) + if (groupingInfo is not null && groupingInfo.IsGrouped) { var items = new List(); @@ -49,14 +49,44 @@ internal static class LayoutFactory2 return items.ToArray(); } + if (layoutHeaderFooterInfo is not null) + { + var items = new List(); + + if (layoutHeaderFooterInfo.HasHeader) + { + items.Add(NSCollectionLayoutBoundarySupplementaryItem.Create( + NSCollectionLayoutSize.Create(width, height), + UICollectionElementKindSectionKey.Header.ToString(), + scrollDirection == UICollectionViewScrollDirection.Vertical + ? NSRectAlignment.Top + : NSRectAlignment.Leading)); + }; + + if (layoutHeaderFooterInfo.HasFooter) + { + items.Add(NSCollectionLayoutBoundarySupplementaryItem.Create( + NSCollectionLayoutSize.Create(width, height), + UICollectionElementKindSectionKey.Footer.ToString(), + scrollDirection == UICollectionViewScrollDirection.Vertical + ? NSRectAlignment.Bottom + : NSRectAlignment.Trailing)); + } + + return items.ToArray(); + } + return []; } - static UICollectionViewLayout CreateListLayout(UICollectionViewScrollDirection scrollDirection, LayoutGroupingInfo groupingInfo, LayoutSnapInfo snapInfo, NSCollectionLayoutDimension itemWidth, NSCollectionLayoutDimension itemHeight, NSCollectionLayoutDimension groupWidth, NSCollectionLayoutDimension groupHeight, double itemSpacing, Func? peekAreaInsetsFunc) + static UICollectionViewLayout CreateListLayout(UICollectionViewScrollDirection scrollDirection, LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo layoutHeaderFooterInfo, LayoutSnapInfo snapInfo, NSCollectionLayoutDimension itemWidth, NSCollectionLayoutDimension itemHeight, NSCollectionLayoutDimension groupWidth, NSCollectionLayoutDimension groupHeight, double itemSpacing, Func? peekAreaInsetsFunc) { var layoutConfiguration = new UICollectionViewCompositionalLayoutConfiguration(); layoutConfiguration.ScrollDirection = scrollDirection; + //create global header and footer + layoutConfiguration.BoundarySupplementaryItems = CreateSupplementaryItems(null, layoutHeaderFooterInfo, scrollDirection, groupWidth, groupHeight); + var layout = new CustomUICollectionViewCompositionalLayout(snapInfo, (sectionIndex, environment) => { // Each item has a size @@ -94,8 +124,10 @@ internal static class LayoutFactory2 var section = NSCollectionLayoutSection.Create(group: group); section.InterGroupSpacing = new NFloat(itemSpacing); + // Create header and footer for group section.BoundarySupplementaryItems = CreateSupplementaryItems( groupingInfo, + null, scrollDirection, groupWidth, groupHeight); @@ -147,6 +179,7 @@ internal static class LayoutFactory2 section.BoundarySupplementaryItems = CreateSupplementaryItems( groupingInfo, + null, // No header/footer in grid scrollDirection, groupWidth, groupHeight); @@ -158,9 +191,10 @@ internal static class LayoutFactory2 } public static UICollectionViewLayout CreateVerticalList(LinearItemsLayout linearItemsLayout, - LayoutGroupingInfo groupingInfo) + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => CreateListLayout(UICollectionViewScrollDirection.Vertical, groupingInfo, + headerFooterInfo, new LayoutSnapInfo { SnapType = linearItemsLayout.SnapPointsType, SnapAligment = linearItemsLayout.SnapPointsAlignment }, // Fill the width NSCollectionLayoutDimension.CreateFractionalWidth(1f), @@ -173,9 +207,10 @@ internal static class LayoutFactory2 public static UICollectionViewLayout CreateHorizontalList(LinearItemsLayout linearItemsLayout, - LayoutGroupingInfo groupingInfo) + LayoutGroupingInfo groupingInfo, LayoutHeaderFooterInfo headerFooterInfo) => CreateListLayout(UICollectionViewScrollDirection.Horizontal, groupingInfo, + headerFooterInfo, new LayoutSnapInfo { SnapType = linearItemsLayout.SnapPointsType, SnapAligment = linearItemsLayout.SnapPointsAlignment }, // Dynamic, estimated width NSCollectionLayoutDimension.CreateEstimated(30f), @@ -186,29 +221,6 @@ internal static class LayoutFactory2 linearItemsLayout.ItemSpacing, null); - public static UICollectionViewLayout CreateVerticalCarousel(LinearItemsLayout linearItemsLayout, Func peekAreaInsets) - => CreateListLayout(UICollectionViewScrollDirection.Vertical, - new LayoutGroupingInfo { IsGrouped = false, HasHeader = false, HasFooter = false }, - new LayoutSnapInfo { SnapType = linearItemsLayout.SnapPointsType, SnapAligment = linearItemsLayout.SnapPointsAlignment }, - // Fill the width and height - NSCollectionLayoutDimension.CreateFractionalWidth(1f), - NSCollectionLayoutDimension.CreateFractionalHeight(1f), - NSCollectionLayoutDimension.CreateFractionalWidth(1f), - NSCollectionLayoutDimension.CreateFractionalHeight(1f), - 0d, peekAreaInsets); - - - public static UICollectionViewLayout CreateHorizontalCarousel(LinearItemsLayout linearItemsLayout, Func peekAreaInsets) - => CreateListLayout(UICollectionViewScrollDirection.Horizontal, - new LayoutGroupingInfo { IsGrouped = false, HasHeader = false, HasFooter = false }, - new LayoutSnapInfo { SnapType = linearItemsLayout.SnapPointsType, SnapAligment = linearItemsLayout.SnapPointsAlignment }, - // Fill the width and height - NSCollectionLayoutDimension.CreateFractionalWidth(1f), - NSCollectionLayoutDimension.CreateFractionalHeight(1f), - NSCollectionLayoutDimension.CreateFractionalWidth(1f), - NSCollectionLayoutDimension.CreateFractionalHeight(1f), - 0d, peekAreaInsets); - public static UICollectionViewLayout CreateVerticalGrid(GridItemsLayout gridItemsLayout, LayoutGroupingInfo groupingInfo) => CreateGridLayout(UICollectionViewScrollDirection.Vertical, diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs index 8151eddc7f..627c7d0518 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cs @@ -1,6 +1,8 @@ #nullable disable using System; using CoreGraphics; +using Foundation; +using Microsoft.Maui.Controls.Handlers.Items; using ObjCRuntime; using UIKit; @@ -14,17 +16,19 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 bool _disposed; - UIView _headerUIView; - VisualElement _headerViewFormsElement; - - UIView _footerUIView; - VisualElement _footerViewFormsElement; - public StructuredItemsViewController2(TItemsView structuredItemsView, UICollectionViewLayout layout) : base(structuredItemsView, layout) { } + protected override void RegisterViewTypes() + { + base.RegisterViewTypes(); + + RegisterSupplementaryViews(UICollectionElementKindSection.Header); + RegisterSupplementaryViews(UICollectionElementKindSection.Footer); + } + protected override void Dispose(bool disposing) { if (_disposed) @@ -36,20 +40,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 if (disposing) { - if (_headerViewFormsElement != null) - { - //_headerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated; - } - if (_footerViewFormsElement != null) - { - //_footerViewFormsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated; - } - - _headerUIView = null; - _headerViewFormsElement = null; - _footerUIView = null; - _footerViewFormsElement = null; } base.Dispose(disposing); @@ -57,6 +48,114 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 protected override bool IsHorizontal => (ItemsView?.ItemsLayout as ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal; + public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, + NSString elementKind, NSIndexPath indexPath) + { + var reuseId = DetermineViewReuseId(elementKind); + + var view = collectionView.DequeueReusableSupplementaryView(elementKind, reuseId, indexPath) as UICollectionReusableView; + + switch (view) + { + case DefaultCell2 defaultCell: + UpdateDefaultSupplementaryView(defaultCell, elementKind); + break; + case TemplatedCell2 templatedCell: + UpdateTemplatedSupplementaryView(templatedCell, elementKind); + break; + } + + return view; + } + + private protected void RegisterSupplementaryViews(UICollectionElementKindSection kind) + { + if (IsHorizontal) + { + CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalSupplementaryView2), + kind, HorizontalSupplementaryView2.ReuseId); + CollectionView.RegisterClassForSupplementaryView(typeof(HorizontalDefaultSupplementalView2), + kind, HorizontalDefaultSupplementalView2.ReuseId); + } + else + { + CollectionView.RegisterClassForSupplementaryView(typeof(VerticalSupplementaryView2), + kind, VerticalSupplementaryView2.ReuseId); + CollectionView.RegisterClassForSupplementaryView(typeof(VerticalDefaultSupplementalView2), + kind, VerticalDefaultSupplementalView2.ReuseId); + } + } + + string DetermineViewReuseId(NSString elementKind) + { + return DetermineViewReuseId(elementKind == UICollectionElementKindSectionKey.Header + ? ItemsView.HeaderTemplate + : ItemsView.FooterTemplate, elementKind == UICollectionElementKindSectionKey.Header + ? ItemsView.Header + : ItemsView.Footer); + } + + void UpdateDefaultSupplementaryView(DefaultCell2 cell, NSString elementKind) + { + var obj = elementKind == UICollectionElementKindSectionKey.Header + ? ItemsView.Header + : ItemsView.Footer; + + cell.Label.Text = obj?.ToString(); + } + + void UpdateTemplatedSupplementaryView(TemplatedCell2 cell, NSString elementKind) + { + bool isHeader = elementKind == UICollectionElementKindSectionKey.Header; + + if(isHeader) + { + if(ItemsView.Header is View headerView) + { + cell.Bind(headerView, ItemsView); + } + else if(ItemsView.HeaderTemplate is not null) + { + cell.Bind(ItemsView.HeaderTemplate, ItemsView.Header, ItemsView); + } + cell.Tag = HeaderTag; + } + else + { + if(ItemsView.Footer is View footerView) + { + cell.Bind(footerView, ItemsView); + } + else if(ItemsView.FooterTemplate is not null) + { + cell.Bind(ItemsView.FooterTemplate, ItemsView.Footer, ItemsView); + } + cell.Tag = FooterTag; + } + } + + string DetermineViewReuseId(DataTemplate template, object item) + { + if (template == null) + { + if (item is View) + { + // No template, but we can fall back to the view + return IsHorizontal + ? HorizontalSupplementaryView2.ReuseId + : VerticalSupplementaryView2.ReuseId; + } + // No template, no item, fall back to the default supplemental views + return IsHorizontal + ? HorizontalDefaultSupplementalView2.ReuseId + : VerticalDefaultSupplementalView2.ReuseId; + } + + return IsHorizontal + ? HorizontalSupplementaryView2.ReuseId + : VerticalSupplementaryView2.ReuseId; + } + protected override CGRect DetermineEmptyViewFrame() { nfloat headerHeight = 0; @@ -78,152 +177,6 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 public override void ViewWillLayoutSubviews() { base.ViewWillLayoutSubviews(); - - // This update is only relevant if you have a footer view because it's used to place the footer view - // based on the ContentSize so we just update the positions if the ContentSize has changed - if (_footerUIView != null) - { - var emptyView = CollectionView.ViewWithTag(EmptyTag); - - if (IsHorizontal) - { - if (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width || - _footerUIView.Frame.X < emptyView?.Frame.X) - UpdateHeaderFooterPosition(); - } - else - { - if (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height || - _footerUIView.Frame.Y < (emptyView?.Frame.Y + emptyView?.Frame.Height)) - UpdateHeaderFooterPosition(); - } - } } - - internal void UpdateFooterView() - { - UpdateSubview(ItemsView?.Footer, ItemsView?.FooterTemplate, FooterTag, - ref _footerUIView, ref _footerViewFormsElement); - UpdateHeaderFooterPosition(); - } - - internal void UpdateHeaderView() - { - UpdateSubview(ItemsView?.Header, ItemsView?.HeaderTemplate, HeaderTag, - ref _headerUIView, ref _headerViewFormsElement); - UpdateHeaderFooterPosition(); - } - - internal void UpdateSubview(object view, DataTemplate viewTemplate, nint viewTag, ref UIView uiView, ref VisualElement formsElement) - { - uiView?.RemoveFromSuperview(); - - if (formsElement != null) - { - ItemsView.RemoveLogicalChild(formsElement); - //formsElement.MeasureInvalidated -= OnFormsElementMeasureInvalidated; - } - - UpdateView(view, viewTemplate, ref uiView, ref formsElement); - - if (uiView != null) - { - uiView.Tag = viewTag; - CollectionView.AddSubview(uiView); - } - - if (formsElement != null) - { - ItemsView.AddLogicalChild(formsElement); - } - - if (formsElement != null) - { - //RemeasureLayout(formsElement); - //formsElement.MeasureInvalidated += OnFormsElementMeasureInvalidated; - } - else - { - uiView?.SizeToFit(); - } - } - - void UpdateHeaderFooterPosition() - { - var emptyView = CollectionView.ViewWithTag(EmptyTag); - - if (IsHorizontal) - { - var currentInset = CollectionView.ContentInset; - - nfloat headerWidth = _headerUIView?.Frame.Width ?? 0f; - nfloat footerWidth = _footerUIView?.Frame.Width ?? 0f; - nfloat emptyWidth = emptyView?.Frame.Width ?? 0f; - - if (_headerUIView != null && _headerUIView.Frame.X != headerWidth) - { - _headerUIView.Frame = new CoreGraphics.CGRect(-headerWidth, 0, headerWidth, CollectionView.Frame.Height); - } - - if (_footerUIView != null && (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width || emptyWidth > 0)) - _footerUIView.Frame = new CoreGraphics.CGRect(ItemsViewLayout.CollectionViewContentSize.Width + emptyWidth, 0, footerWidth, CollectionView.Frame.Height); - - if (CollectionView.ContentInset.Left != headerWidth || CollectionView.ContentInset.Right != footerWidth) - { - var currentOffset = CollectionView.ContentOffset; - CollectionView.ContentInset = new UIEdgeInsets(0, headerWidth, 0, footerWidth); - - var xOffset = currentOffset.X + (currentInset.Left - CollectionView.ContentInset.Left); - - if (CollectionView.ContentSize.Width + headerWidth <= CollectionView.Bounds.Width) - xOffset = -headerWidth; - - // if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move - // this changes the offset of the list by however much the header size has changed - CollectionView.ContentOffset = new CoreGraphics.CGPoint(xOffset, CollectionView.ContentOffset.Y); - } - } - else - { - var currentInset = CollectionView.ContentInset; - nfloat headerHeight = _headerUIView?.Frame.Height ?? 0f; - nfloat footerHeight = _footerUIView?.Frame.Height ?? 0f; - nfloat emptyHeight = emptyView?.Frame.Height ?? 0f; - - if (CollectionView.ContentInset.Top != headerHeight || CollectionView.ContentInset.Bottom != footerHeight) - { - var currentOffset = CollectionView.ContentOffset; - CollectionView.ContentInset = new UIEdgeInsets(headerHeight, 0, footerHeight, 0); - - // if the header grows it will scroll off the screen because if you change the content inset iOS adjusts the content offset so the list doesn't move - // this changes the offset of the list by however much the header size has changed - - var yOffset = currentOffset.Y + (currentInset.Top - CollectionView.ContentInset.Top); - - if (CollectionView.ContentSize.Height + headerHeight <= CollectionView.Bounds.Height) - yOffset = -headerHeight; - - CollectionView.ContentOffset = new CoreGraphics.CGPoint(CollectionView.ContentOffset.X, yOffset); - } - - if (_headerUIView != null && _headerUIView.Frame.Y != headerHeight) - { - _headerUIView.Frame = new CoreGraphics.CGRect(0, -headerHeight, CollectionView.Frame.Width, headerHeight); - } - - nfloat height = 0; - - if (IsViewLoaded && View.Window != null) - { - height = ItemsViewLayout.CollectionViewContentSize.Height; - } - - if (_footerUIView != null && (_footerUIView.Frame.Y != height || emptyHeight > 0)) - { - _footerUIView.Frame = new CoreGraphics.CGRect(0, height + emptyHeight, CollectionView.Frame.Width, footerHeight); - } - } - } - } } \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/TemplatedCell2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/TemplatedCell2.cs index 81f80fb981..6f35bcf7ce 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/TemplatedCell2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/TemplatedCell2.cs @@ -12,7 +12,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 public class TemplatedCell2 : ItemsViewCell2 { internal const string ReuseId = "Microsoft.Maui.Controls.TemplatedCell2"; - + readonly WeakEventManager _weakEventManager = new(); public event EventHandler ContentSizeChanged @@ -51,13 +51,13 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { } - + public UICollectionViewScrollDirection ScrollDirection { get; set; } - - internal IPlatformViewHandler PlatformHandler { get; set; } + + internal IPlatformViewHandler PlatformHandler { get; set; } internal UIView PlatformView { get; set; } - + internal void Unbind() { if (PlatformHandler?.VirtualView is View view) @@ -71,14 +71,14 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 UICollectionViewLayoutAttributes layoutAttributes) { var preferredAttributes = base.PreferredLayoutAttributesFittingAttributes(layoutAttributes); - + if (PlatformHandler?.VirtualView is not null) { if (ScrollDirection == UICollectionViewScrollDirection.Vertical) { var measure = PlatformHandler.VirtualView.Measure(preferredAttributes.Size.Width, double.PositiveInfinity); - + preferredAttributes.Frame = new CGRect(preferredAttributes.Frame.X, preferredAttributes.Frame.Y, preferredAttributes.Frame.Width, measure.Height); @@ -87,15 +87,15 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { var measure = PlatformHandler.VirtualView.Measure(double.PositiveInfinity, preferredAttributes.Size.Height); - + preferredAttributes.Frame = new CGRect(preferredAttributes.Frame.X, preferredAttributes.Frame.Y, measure.Width, preferredAttributes.Frame.Height); } - + preferredAttributes.ZIndex = 2; } - + return preferredAttributes; } @@ -104,7 +104,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 //Unbind(); base.PrepareForReuse(); } - + public void Bind(DataTemplate template, object bindingContext, ItemsView itemsView) { if (PlatformHandler is null) @@ -113,22 +113,46 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 var mauiContext = itemsView.FindMauiContext()!; var nativeView = virtualView!.ToPlatform(mauiContext); - + PlatformView = nativeView; PlatformHandler = virtualView.Handler as IPlatformViewHandler; - + InitializeContentConstraints(nativeView); - + virtualView.BindingContext = bindingContext; } - + if (PlatformHandler?.VirtualView is View view) { view.SetValueFromRenderer(BindableObject.BindingContextProperty, bindingContext); } } - + + public void Bind(View virtualView, ItemsView itemsView) + { + if (PlatformHandler is null && virtualView is not null) + { + var mauiContext = itemsView.FindMauiContext()!; + var nativeView = virtualView!.ToPlatform(mauiContext); + + var mauiWrapperView = new UIContainerView2(virtualView, mauiContext); + + PlatformView = mauiWrapperView; + + PlatformHandler = virtualView.Handler as IPlatformViewHandler; + + InitializeContentConstraints(mauiWrapperView); + + virtualView.BindingContext = itemsView.BindingContext; + } + + if (PlatformHandler?.VirtualView is View view) + { + view.SetValueFromRenderer(BindableObject.BindingContextProperty, itemsView.BindingContext); + } + } + bool IsUsingVSMForSelectionColor(View view) { var groups = VisualStateManager.GetVisualStateGroups(view); @@ -230,7 +254,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 { return; } - + // Prevents the use of default color when there are VisualStateManager with Selected state setting the background color // First we check whether the cell has the default selected background color; if it does, then we should check // to see if the cell content is the VSM to set a selected color @@ -241,4 +265,42 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 } } } + + class UIContainerView2 : UIView + { + readonly IView _view; + readonly IMauiContext _mauiContext; + + public UIContainerView2(IView view, IMauiContext mauiContext) + { + _view = view; + _mauiContext = mauiContext; + UpdatePlatformView(); + ClipsToBounds = true; + } + + internal void UpdatePlatformView() + { + var handler = _view.ToHandler(_mauiContext); + var nativeView = _view.ToPlatform(); + + if (nativeView.Superview == this) + { + nativeView.RemoveFromSuperview(); + } + + AddSubview(nativeView); + } + + public override void LayoutSubviews() + { + _view?.Arrange(new Rect(0, 0, Frame.Width, Frame.Height)); + base.LayoutSubviews(); + } + + public override CGSize SizeThatFits(CGSize size) + { + return _view.Measure(size.Width, size.Height).ToCGSize(); + } + } } diff --git a/src/Controls/src/Core/Handlers/Items2/iOS/VerticalDefaultSupplementalView2.cs b/src/Controls/src/Core/Handlers/Items2/iOS/VerticalDefaultSupplementalView2.cs index 6982146b52..f6110d1fa8 100644 --- a/src/Controls/src/Core/Handlers/Items2/iOS/VerticalDefaultSupplementalView2.cs +++ b/src/Controls/src/Core/Handlers/Items2/iOS/VerticalDefaultSupplementalView2.cs @@ -20,15 +20,5 @@ namespace Microsoft.Maui.Controls.Handlers.Items2 Constraint.Priority = (float)UILayoutPriority.DefaultHigh; Constraint.Active = true; } - - // public override void ConstrainTo(CGSize constraint) - // { - // Constraint.Constant = constraint.Width; - // } - // - // public override CGSize Measure() - // { - // return new CGSize(Constraint.Constant, Label.IntrinsicContentSize.Height); - // } } } \ No newline at end of file diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt index 82744bf66c..cddde56ac9 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt @@ -7590,7 +7590,6 @@ override Microsoft.Maui.Controls.ItemsView.OnBindingContextChanged() -> void override Microsoft.Maui.Controls.ItemsView.OnMeasure(double widthConstraint, double heightConstraint) -> Microsoft.Maui.SizeRequest override Microsoft.Maui.Controls.Label.OnBindingContextChanged() -> void override Microsoft.Maui.Controls.Layout.InvalidateMeasureOverride() -> void -override Microsoft.Maui.Controls.Layout.Measure(double widthConstraint, double heightConstraint, Microsoft.Maui.Controls.MeasureFlags flags = Microsoft.Maui.Controls.MeasureFlags.None) -> Microsoft.Maui.SizeRequest override Microsoft.Maui.Controls.LinearGradientBrush.IsEmpty.get -> bool override Microsoft.Maui.Controls.ListView.OnBindingContextChanged() -> void override Microsoft.Maui.Controls.ListView.OnMeasure(double widthConstraint, double heightConstraint) -> Microsoft.Maui.SizeRequest diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt index 6e129edb83..62acbb19df 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt @@ -4,8 +4,6 @@ const Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2.E const Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.FooterTag = 222 -> int const Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.HeaderTag = 111 -> int Microsoft.Maui.Controls.HandlerProperties -Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2 -Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2.CarouselTemplatedCell2(CoreGraphics.CGRect frame) -> void Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2 Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 @@ -93,16 +91,12 @@ override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PreferredS override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersStatusBarHidden() -> bool override Microsoft.Maui.Controls.GradientBrush.IsEmpty.get -> bool override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.IsHorizontal.get -> bool -override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.UpdateItemsSource() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.UpdateVisibility() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewDidLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewDidLoad() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewWillLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2.GetVisibleItemsIndex() -> (bool VisibleItems, int First, int Center, int Last) -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CreateController(Microsoft.Maui.Controls.ReorderableItemsView! itemsView, UIKit.UICollectionViewLayout! layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2! -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.ScrollToRequested(object! sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs! args) -> void -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout! override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.UpdateItemsSource() -> void override Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2.Dispose(bool disposing) -> void @@ -113,6 +107,7 @@ override Microsoft.Maui.Controls.Handlers.Items2.ReorderableItemsViewController2 override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.DetermineEmptyViewFrame() -> CoreGraphics.CGRect override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.Dispose(bool disposing) -> void override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.IsHorizontal.get -> bool +override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.ViewWillLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.PrepareForReuse() -> void override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Selected.get -> bool @@ -204,16 +199,6 @@ Microsoft.Maui.Controls.TimeChangedEventArgs.TimeChangedEventArgs(System.TimeSpa Microsoft.Maui.Controls.TimePicker.TimeSelected -> System.EventHandler static Microsoft.Maui.Controls.HandlerProperties.GetDisconnectPolicy(Microsoft.Maui.Controls.BindableObject! target) -> Microsoft.Maui.HandlerDisconnectPolicy static Microsoft.Maui.Controls.HandlerProperties.SetDisconnectPolicy(Microsoft.Maui.Controls.BindableObject! target, Microsoft.Maui.HandlerDisconnectPolicy value) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapCanReorderItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.ReorderableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapFooterTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapHeaderTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapIsGrouped(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.GroupableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemSizingStrategy(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsLayout(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsSource(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItem(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectionMode(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void static readonly Microsoft.Maui.Controls.HandlerProperties.DisconnectPolicyProperty -> Microsoft.Maui.Controls.BindableProperty! override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersHomeIndicatorAutoHidden.get -> bool override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation @@ -303,6 +288,8 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.CarouselViewController2(Microsoft.Maui.Controls.CarouselView itemsView, UIKit.UICollectionViewLayout layout) -> void ~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2.CarouselViewDelegator2(UIKit.UICollectionViewLayout itemsViewLayout, Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 ItemsViewController2) -> void +~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.CarouselViewHandler2(Microsoft.Maui.PropertyMapper mapper = null) -> void +~Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CollectionViewHandler2(Microsoft.Maui.PropertyMapper mapper = null) -> void ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Constraint.get -> UIKit.NSLayoutConstraint ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Constraint.set -> void ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Label.get -> UIKit.UILabel @@ -344,6 +331,7 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2 ~Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.StructuredItemsViewController2(TItemsView structuredItemsView, UIKit.UICollectionViewLayout layout) -> void ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Bind(Microsoft.Maui.Controls.DataTemplate template, object bindingContext, Microsoft.Maui.Controls.ItemsView itemsView) -> void +~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Bind(Microsoft.Maui.Controls.View virtualView, Microsoft.Maui.Controls.ItemsView itemsView) -> void ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.CurrentTemplate.get -> Microsoft.Maui.Controls.DataTemplate ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.OnLayoutAttributesChanged(UIKit.UICollectionViewLayoutAttributes newAttributes) -> void ~Microsoft.Maui.Controls.InputView.FontFamily.get -> string @@ -365,6 +353,9 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.CreateController(Microsoft.Maui.Controls.CarouselView newElement, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.ScrollToRequested(object sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs args) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CreateController(Microsoft.Maui.Controls.ReorderableItemsView itemsView, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2 +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.ScrollToRequested(object sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs args) -> void +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.CreateDelegator() -> UIKit.UICollectionViewDelegateFlowLayout ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.CreateItemsViewSource() -> Microsoft.Maui.Controls.Handlers.Items.IItemsViewSource ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.GetViewForSupplementaryElement(UIKit.UICollectionView collectionView, Foundation.NSString elementKind, Foundation.NSIndexPath indexPath) -> UIKit.UICollectionReusableView @@ -390,6 +381,7 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewController2.ItemSelected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewDelegator2.ItemDeselected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewDelegator2.ItemSelected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void +~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.GetViewForSupplementaryElement(UIKit.UICollectionView collectionView, Foundation.NSString elementKind, Foundation.NSIndexPath indexPath) -> UIKit.UICollectionReusableView ~override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.PreferredLayoutAttributesFittingAttributes(UIKit.UICollectionViewLayoutAttributes layoutAttributes) -> UIKit.UICollectionViewLayoutAttributes ~override Microsoft.Maui.Controls.ImageButton.OnPropertyChanged(string propertyName = null) -> void ~override Microsoft.Maui.Controls.Handlers.Compatibility.PhoneFlyoutPageRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void @@ -408,13 +400,24 @@ override Microsoft.Maui.Controls.SearchBar.IsEnabledCore.get -> bool ~override Microsoft.Maui.Controls.Region.Equals(object obj) -> bool ~override Microsoft.Maui.Controls.Shapes.Matrix.Equals(object obj) -> bool ~override Microsoft.Maui.Controls.ShellContent.OnPropertyChanged(string propertyName = null) -> void -~static Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2.ReuseId -> Foundation.NSString ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapCurrentItem(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapIsBounceEnabled(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapIsSwipeEnabled(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapLoop(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapPeekAreaInsets(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.Mapper -> Microsoft.Maui.PropertyMapper ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapPosition(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapCanReorderItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.ReorderableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapFooterTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapHeaderTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapIsGrouped(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.GroupableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemSizingStrategy(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsLayout(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsSource(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.Mapper -> Microsoft.Maui.PropertyMapper +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItem(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectionMode(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.ItemsViewMapper -> Microsoft.Maui.PropertyMapper> ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.MapEmptyView(Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2 handler, Microsoft.Maui.Controls.ItemsView itemsView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.MapEmptyViewTemplate(Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2 handler, Microsoft.Maui.Controls.ItemsView itemsView) -> void @@ -592,4 +595,4 @@ Microsoft.Maui.Controls.StyleableElement.class.set -> void *REMOVED*~Microsoft.Maui.Controls.NavigableElement.Style.get -> Microsoft.Maui.Controls.Style *REMOVED*~Microsoft.Maui.Controls.NavigableElement.Style.set -> void *REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.get -> System.Collections.Generic.IList -*REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.set -> void +*REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.set -> void \ No newline at end of file diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt index 5857b8ee97..e34622462a 100644 --- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt @@ -4,8 +4,6 @@ const Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2.E const Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.FooterTag = 222 -> int const Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.HeaderTag = 111 -> int Microsoft.Maui.Controls.HandlerProperties -Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2 -Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2.CarouselTemplatedCell2(CoreGraphics.CGRect frame) -> void Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2 Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 @@ -90,16 +88,12 @@ override Microsoft.Maui.Controls.Handlers.Compatibility.CellRenderer.Invoke(stri override Microsoft.Maui.Controls.Handlers.Compatibility.CellRenderer.UpdateValue(string! property) -> void override Microsoft.Maui.Controls.GradientBrush.IsEmpty.get -> bool override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.IsHorizontal.get -> bool -override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.UpdateItemsSource() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.UpdateVisibility() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewDidLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewDidLoad() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.ViewWillLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2.GetVisibleItemsIndex() -> (bool VisibleItems, int First, int Center, int Last) -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CreateController(Microsoft.Maui.Controls.ReorderableItemsView! itemsView, UIKit.UICollectionViewLayout! layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2! -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.ScrollToRequested(object! sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs! args) -> void -override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout! override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.UpdateItemsSource() -> void override Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2.Dispose(bool disposing) -> void @@ -110,6 +104,7 @@ override Microsoft.Maui.Controls.Handlers.Items2.ReorderableItemsViewController2 override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.DetermineEmptyViewFrame() -> CoreGraphics.CGRect override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.Dispose(bool disposing) -> void override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.IsHorizontal.get -> bool +override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.RegisterViewTypes() -> void override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.ViewWillLayoutSubviews() -> void override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.PrepareForReuse() -> void override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Selected.get -> bool @@ -198,16 +193,6 @@ Microsoft.Maui.Controls.TimeChangedEventArgs.TimeChangedEventArgs(System.TimeSpa Microsoft.Maui.Controls.TimePicker.TimeSelected -> System.EventHandler static Microsoft.Maui.Controls.HandlerProperties.GetDisconnectPolicy(Microsoft.Maui.Controls.BindableObject! target) -> Microsoft.Maui.HandlerDisconnectPolicy static Microsoft.Maui.Controls.HandlerProperties.SetDisconnectPolicy(Microsoft.Maui.Controls.BindableObject! target, Microsoft.Maui.HandlerDisconnectPolicy value) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapCanReorderItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.ReorderableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapFooterTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapHeaderTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapIsGrouped(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.GroupableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemSizingStrategy(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsLayout(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.StructuredItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsSource(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItem(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void -static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectionMode(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2! handler, Microsoft.Maui.Controls.SelectableItemsView! itemsView) -> void static readonly Microsoft.Maui.Controls.HandlerProperties.DisconnectPolicyProperty -> Microsoft.Maui.Controls.BindableProperty! Microsoft.Maui.Controls.WebView.ProcessTerminated -> System.EventHandler Microsoft.Maui.Controls.WebViewProcessTerminatedEventArgs @@ -297,6 +282,8 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2.CarouselViewController2(Microsoft.Maui.Controls.CarouselView itemsView, UIKit.UICollectionViewLayout layout) -> void ~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewDelegator2.CarouselViewDelegator2(UIKit.UICollectionViewLayout itemsViewLayout, Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 ItemsViewController2) -> void +~Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.CarouselViewHandler2(Microsoft.Maui.PropertyMapper mapper = null) -> void +~Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CollectionViewHandler2(Microsoft.Maui.PropertyMapper mapper = null) -> void ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Constraint.get -> UIKit.NSLayoutConstraint ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Constraint.set -> void ~Microsoft.Maui.Controls.Handlers.Items2.DefaultCell2.Label.get -> UIKit.UILabel @@ -338,6 +325,7 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2 ~Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.StructuredItemsViewController2(TItemsView structuredItemsView, UIKit.UICollectionViewLayout layout) -> void ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Bind(Microsoft.Maui.Controls.DataTemplate template, object bindingContext, Microsoft.Maui.Controls.ItemsView itemsView) -> void +~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.Bind(Microsoft.Maui.Controls.View virtualView, Microsoft.Maui.Controls.ItemsView itemsView) -> void ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.CurrentTemplate.get -> Microsoft.Maui.Controls.DataTemplate ~Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.OnLayoutAttributesChanged(UIKit.UICollectionViewLayoutAttributes newAttributes) -> void ~Microsoft.Maui.Controls.InputView.FontFamily.get -> string @@ -359,6 +347,9 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.CreateController(Microsoft.Maui.Controls.CarouselView newElement, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.CarouselViewController2 ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.ScrollToRequested(object sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs args) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.CreateController(Microsoft.Maui.Controls.ReorderableItemsView itemsView, UIKit.UICollectionViewLayout layout) -> Microsoft.Maui.Controls.Handlers.Items2.ItemsViewController2 +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.ScrollToRequested(object sender, Microsoft.Maui.Controls.ScrollToRequestEventArgs args) -> void +~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.SelectLayout() -> UIKit.UICollectionViewLayout ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.CreateDelegator() -> UIKit.UICollectionViewDelegateFlowLayout ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.CreateItemsViewSource() -> Microsoft.Maui.Controls.Handlers.Items.IItemsViewSource ~override Microsoft.Maui.Controls.Handlers.Items2.GroupableItemsViewController2.GetViewForSupplementaryElement(UIKit.UICollectionView collectionView, Foundation.NSString elementKind, Foundation.NSIndexPath indexPath) -> UIKit.UICollectionReusableView @@ -384,6 +375,7 @@ Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewController2.ItemSelected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewDelegator2.ItemDeselected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void ~override Microsoft.Maui.Controls.Handlers.Items2.SelectableItemsViewDelegator2.ItemSelected(UIKit.UICollectionView collectionView, Foundation.NSIndexPath indexPath) -> void +~override Microsoft.Maui.Controls.Handlers.Items2.StructuredItemsViewController2.GetViewForSupplementaryElement(UIKit.UICollectionView collectionView, Foundation.NSString elementKind, Foundation.NSIndexPath indexPath) -> UIKit.UICollectionReusableView ~override Microsoft.Maui.Controls.Handlers.Items2.TemplatedCell2.PreferredLayoutAttributesFittingAttributes(UIKit.UICollectionViewLayoutAttributes layoutAttributes) -> UIKit.UICollectionViewLayoutAttributes ~override Microsoft.Maui.Controls.ImageButton.OnPropertyChanged(string propertyName = null) -> void ~override Microsoft.Maui.Controls.Handlers.Compatibility.PhoneFlyoutPageRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void @@ -401,13 +393,24 @@ override Microsoft.Maui.Controls.SearchBar.IsEnabledCore.get -> bool ~Microsoft.Maui.Controls.WebView.UserAgent.set -> void ~override Microsoft.Maui.Controls.Region.Equals(object obj) -> bool ~override Microsoft.Maui.Controls.Shapes.Matrix.Equals(object obj) -> bool -~static Microsoft.Maui.Controls.Handlers.Items2.CarouselTemplatedCell2.ReuseId -> Foundation.NSString ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapCurrentItem(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapIsBounceEnabled(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapIsSwipeEnabled(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapLoop(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapPeekAreaInsets(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.MapPosition(Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2 handler, Microsoft.Maui.Controls.CarouselView carouselView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2.Mapper -> Microsoft.Maui.PropertyMapper +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapCanReorderItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.ReorderableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapFooterTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapHeaderTemplate(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapIsGrouped(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.GroupableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemSizingStrategy(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsLayout(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.StructuredItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapItemsSource(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.Mapper -> Microsoft.Maui.PropertyMapper +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItem(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectedItems(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void +~static Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.MapSelectionMode(Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2 handler, Microsoft.Maui.Controls.SelectableItemsView itemsView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.ItemsViewMapper -> Microsoft.Maui.PropertyMapper> ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.MapEmptyView(Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2 handler, Microsoft.Maui.Controls.ItemsView itemsView) -> void ~static Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2.MapEmptyViewTemplate(Microsoft.Maui.Controls.Handlers.Items2.ItemsViewHandler2 handler, Microsoft.Maui.Controls.ItemsView itemsView) -> void @@ -592,4 +595,4 @@ Microsoft.Maui.Controls.StyleableElement.class.set -> void *REMOVED*~Microsoft.Maui.Controls.NavigableElement.Style.get -> Microsoft.Maui.Controls.Style *REMOVED*~Microsoft.Maui.Controls.NavigableElement.Style.set -> void *REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.get -> System.Collections.Generic.IList -*REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.set -> void +*REMOVED*~Microsoft.Maui.Controls.NavigableElement.StyleClass.set -> void \ No newline at end of file diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue10234.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue10234.cs index 59d96ded5d..cfe3208351 100644 --- a/src/Controls/tests/TestCases.HostApp/Issues/Issue10234.cs +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue10234.cs @@ -84,7 +84,7 @@ namespace Maui.Controls.Sample.Issues () => { var image = new Image(); - image.SetBinding(Image.SourceProperty, new Binding(".")); + image.SetBinding(Image.SourceProperty, new Binding(nameof(PhotoItem.Image))); return image; } ) @@ -106,19 +106,18 @@ namespace Maui.Controls.Sample.Issues Content = grid; } - public ObservableCollection Items { get; set; } + public ObservableCollection Items { get; set; } public void LoadData() { - var images = new List(); + var images = new List(); - images.Add("oasis.jpg"); - images.Add("dotnet_bot.jpg"); - images.Add("shopping_cart.jpg"); - images.Add("groceries.png"); + for (int i = 0; i < 4; i++) + { + images.Add(new PhotoItem { Image = "oasis.jpg", Title = $"Title {i}" }); + } - - Items = new ObservableCollection(images); + Items = new ObservableCollection(images); Photos.ItemsSource = Items; } @@ -134,5 +133,11 @@ namespace Maui.Controls.Sample.Issues get; set; } } + + class PhotoItem + { + public string Image { get; set; } + public string Title { get; set; } + } } } diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue19379.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue19379.xaml index 06d7743e90..0a6107fd37 100644 --- a/src/Controls/tests/TestCases.HostApp/Issues/Issue19379.xaml +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue19379.xaml @@ -3,13 +3,14 @@ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Maui.Controls.Sample.Issues.Issue19379" xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues"> - + RowSpacing="25" + RowDefinitions="Auto,*,Auto">