From 3d28f7dafe59341954122e8088b545f77a9bc3c4 Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Thu, 28 Feb 2019 13:02:49 -0700 Subject: [PATCH] Fix iOS EmptyView crash; properly handle EmptyView swapping (#5353) --- .../EmptyViewGalleries/EmptyViewGallery.cs | 2 + .../EmptyViewGalleries/EmptyViewSwapGallery.xaml | 51 ++++++++++++++++++++++ .../EmptyViewSwapGallery.xaml.cs | 47 ++++++++++++++++++++ .../Xamarin.Forms.Controls.csproj | 3 ++ .../CollectionView/ItemsViewController.cs | 35 +++++++-------- 5 files changed, 121 insertions(+), 17 deletions(-) create mode 100644 Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml create mode 100644 Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml.cs diff --git a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewGallery.cs b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewGallery.cs index b466fab..5d12406 100644 --- a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewGallery.cs +++ b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewGallery.cs @@ -24,6 +24,8 @@ new EmptyViewViewGallery(), Navigation), GalleryBuilder.NavButton("EmptyView (Template View)", () => new EmptyViewTemplateGallery(), Navigation), + GalleryBuilder.NavButton("EmptyView (Swap EmptyView)", () => + new EmptyViewSwapGallery(), Navigation), GalleryBuilder.NavButton("EmptyView (load simulation)", () => new EmptyViewLoadSimulateGallery(), Navigation), } diff --git a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml new file mode 100644 index 0000000..89c4af1 --- /dev/null +++ b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml.cs b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml.cs new file mode 100644 index 0000000..2c73c74 --- /dev/null +++ b/Xamarin.Forms.Controls/GalleryPages/CollectionViewGalleries/EmptyViewGalleries/EmptyViewSwapGallery.xaml.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Xamarin.Forms; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.EmptyViewGalleries +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + public partial class EmptyViewSwapGallery : ContentPage + { + readonly DemoFilteredItemSource _demoFilteredItemSource = new DemoFilteredItemSource(); + + public EmptyViewSwapGallery() + { + InitializeComponent(); + + CollectionView.ItemTemplate = ExampleTemplates.PhotoTemplate(); + + CollectionView.ItemsSource = _demoFilteredItemSource.Items; + + SearchBar.SearchCommand = new Command(() => + { + _demoFilteredItemSource.FilterItems(SearchBar.Text); + }); + + EmptyViewSwitch.Toggled += EmptyViewSwitchToggled; + + SwitchEmptyView(); + } + + private void EmptyViewSwitchToggled(object sender, ToggledEventArgs e) + { + SwitchEmptyView(); + } + + void SwitchEmptyView() + { + CollectionView.EmptyView = EmptyViewSwitch.IsToggled + ? Resources["EmptyView1"] + : Resources["EmptyView2"]; + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj index a746806..6c944a4 100644 --- a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj +++ b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj @@ -52,6 +52,9 @@ MSBuild:UpdateDesignTimeXaml + + MSBuild:UpdateDesignTimeXaml + MSBuild:UpdateDesignTimeXaml diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs b/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs index f9756f9..8b52736 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs @@ -13,6 +13,7 @@ namespace Xamarin.Forms.Platform.iOS ItemsViewLayout _layout; bool _initialConstraintsSet; bool _wasEmpty; + bool _currentBackgroundIsEmptyView; UIView _backgroundUIView; UIView _emptyUIView; @@ -232,20 +233,11 @@ namespace Xamarin.Forms.Platform.iOS if (emptyView == null) { - // Nope, no EmptyView set. So nothing to display. If there _was_ a background view on the UICollectionView, - // we should restore it here (in case the EmptyView _used to be_ set, and has been un-set) - if(_backgroundUIView != null) - { - CollectionView.BackgroundView = _backgroundUIView; - } - - // Also, clear the cached version + // Clear the cached Forms and native views _emptyUIView = null; - - return; + _emptyViewFormsElement = null; } - - if (_emptyUIView == null) + else { // Create the native renderer for the EmptyView, and keep the actual Forms element (if any) // around for updating the layout later @@ -253,18 +245,25 @@ namespace Xamarin.Forms.Platform.iOS _emptyUIView = NativeView; _emptyViewFormsElement = FormsElement; } + + // If the empty view is being displayed, we might need to update it + UpdateEmptyViewVisibility(_itemsSource?.Count == 0); } void UpdateEmptyViewVisibility(bool isEmpty) { - if (isEmpty) + if (isEmpty && _emptyUIView != null) { - // Cache any existing background view so we can restore it later - _backgroundUIView = CollectionView.BackgroundView; + if (!_currentBackgroundIsEmptyView) + { + // Cache any existing background view so we can restore it later + _backgroundUIView = CollectionView.BackgroundView; + } - // Replace any current background with the EmptyView. This will also set the native view's frame + // Replace any current background with the EmptyView. This will also set the native empty view's frame // to match the UICollectionView's frame CollectionView.BackgroundView = _emptyUIView; + _currentBackgroundIsEmptyView = true; if (_emptyViewFormsElement != null) { @@ -276,10 +275,12 @@ namespace Xamarin.Forms.Platform.iOS else { // Is the empty view currently in the background? Swap back to the default. - if (CollectionView.BackgroundView == _emptyUIView) + if (_currentBackgroundIsEmptyView) { CollectionView.BackgroundView = _backgroundUIView; } + + _currentBackgroundIsEmptyView = false; } } -- 2.7.4