From ed57fe372c994c91a427aec9ece6571d71d49d1c Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Fri, 20 Sep 2019 11:37:15 -0600 Subject: [PATCH] Make sure transition from empty CollectionView measures cell size; fixes #7472 (#7580) fixes #7472 fixes #7548 --- .../CollectionViewGallery.cs | 41 ++++++++++--------- .../CollectionView/ItemsViewController.cs | 8 ++++ .../CollectionView/ObservableItemsSource.cs | 22 ++++++---- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/CollectionViewGallery.cs b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/CollectionViewGallery.cs index 6e2e5d8a40e..be9b989579f 100644 --- a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/CollectionViewGallery.cs +++ b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/CollectionViewGallery.cs @@ -14,26 +14,29 @@ public class CollectionViewGallery : ContentPage { public CollectionViewGallery() { - Content = new StackLayout + Content = new ScrollView { - Children = - { - new Button { Text ="Enable CollectionView", AutomationId = "EnableCollectionView", Command = new Command(() => Device.SetFlags(new[] { ExperimentalFlags.CollectionViewExperimental })) }, - GalleryBuilder.NavButton("Default Text Galleries", () => new DefaultTextGallery(), Navigation), - GalleryBuilder.NavButton("DataTemplate Galleries", () => new DataTemplateGallery(), Navigation), - GalleryBuilder.NavButton("Observable Collection Galleries", () => new ObservableCollectionGallery(), Navigation), - GalleryBuilder.NavButton("Snap Points Galleries", () => new SnapPointsGallery(), Navigation), - GalleryBuilder.NavButton("ScrollTo Galleries", () => new ScrollToGallery(), Navigation), - GalleryBuilder.NavButton("CarouselView Galleries", () => new CarouselViewGallery(), Navigation), - GalleryBuilder.NavButton("EmptyView Galleries", () => new EmptyViewGallery(), Navigation), - GalleryBuilder.NavButton("Selection Galleries", () => new SelectionGallery(), Navigation), - GalleryBuilder.NavButton("Propagation Galleries", () => new PropagationGallery(), Navigation), - GalleryBuilder.NavButton("Grouping Galleries", () => new GroupingGallery(), Navigation), - GalleryBuilder.NavButton("Item Size Galleries", () => new ItemsSizeGallery(), Navigation), - GalleryBuilder.NavButton("Scroll Mode Galleries", () => new ScrollModeGallery(), Navigation), - GalleryBuilder.NavButton("Alternate Layout Galleries", () => new AlternateLayoutGallery(), Navigation), - GalleryBuilder.NavButton("Header/Footer Galleries", () => new HeaderFooterGallery(), Navigation), - GalleryBuilder.NavButton("Nested CollectionViews", () => new NestedGalleries.NestedCollectionViewGallery(), Navigation), + Content = new StackLayout + { + Children = + { + new Button { Text ="Enable CollectionView", AutomationId = "EnableCollectionView", Command = new Command(() => Device.SetFlags(new[] { ExperimentalFlags.CollectionViewExperimental })) }, + GalleryBuilder.NavButton("Default Text Galleries", () => new DefaultTextGallery(), Navigation), + GalleryBuilder.NavButton("DataTemplate Galleries", () => new DataTemplateGallery(), Navigation), + GalleryBuilder.NavButton("Observable Collection Galleries", () => new ObservableCollectionGallery(), Navigation), + GalleryBuilder.NavButton("Snap Points Galleries", () => new SnapPointsGallery(), Navigation), + GalleryBuilder.NavButton("ScrollTo Galleries", () => new ScrollToGallery(), Navigation), + GalleryBuilder.NavButton("CarouselView Galleries", () => new CarouselViewGallery(), Navigation), + GalleryBuilder.NavButton("EmptyView Galleries", () => new EmptyViewGallery(), Navigation), + GalleryBuilder.NavButton("Selection Galleries", () => new SelectionGallery(), Navigation), + GalleryBuilder.NavButton("Propagation Galleries", () => new PropagationGallery(), Navigation), + GalleryBuilder.NavButton("Grouping Galleries", () => new GroupingGallery(), Navigation), + GalleryBuilder.NavButton("Item Size Galleries", () => new ItemsSizeGallery(), Navigation), + GalleryBuilder.NavButton("Scroll Mode Galleries", () => new ScrollModeGallery(), Navigation), + GalleryBuilder.NavButton("Alternate Layout Galleries", () => new AlternateLayoutGallery(), Navigation), + GalleryBuilder.NavButton("Header/Footer Galleries", () => new HeaderFooterGallery(), Navigation), + GalleryBuilder.NavButton("Nested CollectionViews", () => new NestedGalleries.NestedCollectionViewGallery(), Navigation), + } } }; } diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs b/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs index a8ffeb33edf..e1bed541742 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs @@ -112,6 +112,14 @@ void CheckForEmptySource() { UpdateEmptyViewVisibility(_isEmpty); } + + if (wasEmpty && !_isEmpty) + { + // If we're going from empty to having stuff, it's possible that we've never actually measured + // a prototype cell and our itemSize or estimatedItemSize are wrong/unset + // So trigger a constraint update; if we need a measurement, that will make it happen + ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); + } } public override void ViewDidLoad() diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/ObservableItemsSource.cs b/Xamarin.Forms.Platform.iOS/CollectionView/ObservableItemsSource.cs index cb644982217..6b881cdc194 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/ObservableItemsSource.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/ObservableItemsSource.cs @@ -135,17 +135,21 @@ void Add(NotifyCollectionChangedEventArgs args) var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]); var count = args.NewItems.Count; - _collectionView.PerformBatchUpdates(() => + if (!_grouped && _collectionView.NumberOfSections() != GroupCount && count > 0) { - if (!_grouped && _collectionView.NumberOfSections() != GroupCount) + // Okay, we're going from completely empty to more than 0 items; this means we don't even + // have a section 0 yet. Inserting a section 0 manually results in an unexplained crash, so instead + // we'll just reload the data so the UICollectionView can get its internal state sorted out. + _collectionView.ReloadData(); + } + else + { + _collectionView.PerformBatchUpdates(() => { - // We had an empty non-grouped list, and now we're trying to add an item; - // we need to give it a section as well - _collectionView.InsertSections(new NSIndexSet(0)); - } - - _collectionView.InsertItems(CreateIndexesFrom(startIndex, count)); - }, null); + var indexes = CreateIndexesFrom(startIndex, count); + _collectionView.InsertItems(indexes); + }, null); + } } void Remove(NotifyCollectionChangedEventArgs args)