Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit facdba4

Browse files
authored
Prevent CollectionView.EmptyView from showing up while it shouldn't on iOS (#15122)
* Add repro + fix * Fix build + Add Item Remove button * Tidy up
1 parent 68a7ea3 commit facdba4

File tree

5 files changed

+224
-2
lines changed

5 files changed

+224
-2
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!-- Used in Issue13794 -->
3+
<CollectionView
4+
xmlns="http://xamarin.com/schemas/2014/forms"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
x:Class="Xamarin.Forms.Controls.Issues.MyCollectionView"
7+
ItemsSource="{Binding Data}"
8+
SelectionMode="Single"
9+
SelectionChanged="CollectionView_SelectionChanged"
10+
AutomationId="TehCollectionView">
11+
12+
<CollectionView.EmptyView>
13+
<Label Text="The collection is empty" BackgroundColor="Transparent" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" AutomationId="CollectionViewEmptyView" />
14+
</CollectionView.EmptyView>
15+
16+
<CollectionView.ItemTemplate>
17+
<DataTemplate>
18+
<SwipeView>
19+
<SwipeView.RightItems>
20+
<SwipeItems>
21+
<SwipeItem Text="Delete" BackgroundColor="Red" Invoked="DeleteItem_Invoked" />
22+
</SwipeItems>
23+
</SwipeView.RightItems>
24+
25+
26+
<Label Text="{Binding .}" Padding="20" />
27+
28+
</SwipeView>
29+
</DataTemplate>
30+
</CollectionView.ItemTemplate>
31+
32+
</CollectionView>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.ObjectModel;
3+
using System.Linq;
4+
using Xamarin.Forms;
5+
6+
namespace Xamarin.Forms.Controls.Issues
7+
{
8+
public partial class MyCollectionView : CollectionView
9+
{
10+
public ObservableCollection<string> Data { get; private set; }
11+
12+
public MyCollectionView(ObservableCollection<string> data)
13+
{
14+
#if APP
15+
InitializeComponent();
16+
#endif
17+
BindingContext = this;
18+
19+
// Moving this above InitializeComponent fixes the problem.
20+
Data = data;
21+
}
22+
23+
void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
24+
{
25+
if (e.CurrentSelection == null || e.CurrentSelection.Count == 0)
26+
{
27+
return;
28+
}
29+
30+
SelectedItem = null;
31+
32+
if (e.CurrentSelection.FirstOrDefault() is String data)
33+
{
34+
Console.WriteLine($"Selected: {data}");
35+
}
36+
}
37+
38+
void DeleteItem_Invoked(System.Object sender, System.EventArgs e)
39+
{
40+
if (sender is SwipeItem swipeItem && swipeItem.BindingContext is String dataItem)
41+
{
42+
Data.Remove(dataItem);
43+
}
44+
}
45+
}
46+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
using Xamarin.Forms.CustomAttributes;
5+
using Xamarin.Forms.Internals;
6+
7+
#if UITEST
8+
using NUnit.Framework;
9+
using Xamarin.Forms.Core.UITests;
10+
#endif
11+
12+
namespace Xamarin.Forms.Controls.Issues
13+
{
14+
#if UITEST
15+
[NUnit.Framework.Category(UITestCategories.CollectionView)]
16+
#endif
17+
[Preserve(AllMembers = true)]
18+
[Issue(IssueTracker.Github, 13794, "[Bug] CollectionView iOS draws both EmptyView and Items/ItemTemplate", PlatformAffected.iOS)]
19+
public class Issue13794 : TestContentPage
20+
{
21+
ObservableCollection<string> _data;
22+
MyCollectionView _myCollectionView;
23+
24+
public Issue13794()
25+
{
26+
ToolbarItems.Add(new ToolbarItem("Remove item", null, () => { if (_myCollectionView.Data.Count >= 1) _myCollectionView.Data.RemoveAt(0); }));
27+
28+
var carouselView = new CarouselView()
29+
{
30+
IsSwipeEnabled = false
31+
};
32+
33+
BindingContext = this;
34+
35+
// This is gross, but the idea is the page contains the data and passes a refernece to the view.
36+
// Data is loaded from the page (eg via web request, loaded from file)
37+
_data = new ObservableCollection<string>();
38+
39+
_myCollectionView = new MyCollectionView(_data);
40+
41+
// In my code I was replacing the Footer already defined in the xaml.
42+
// This didn't seem to contribute to the issue.
43+
//_myCollectionView.Footer = new BoxView();
44+
45+
// Add collection view to a CarouselView. This was the only way I could replicate the issue.
46+
// In my actual app I have 3 different user feeds, and user can change between them.
47+
carouselView.ItemsSource = new List<View>()
48+
{
49+
_myCollectionView,
50+
};
51+
52+
// This makes more sense when there is 3 differnet things to select.
53+
carouselView.ItemTemplate = new MyDataTemplateSelector()
54+
{
55+
MyCollectionViewDataTemplate = new DataTemplate(() => _myCollectionView),
56+
};
57+
58+
// I was trying to set _myCollectionView as root Content but it doesn't appear to
59+
// cause the problem. Its related to the CarouselView
60+
//Content = _myCollectionView;
61+
62+
// Add data
63+
var rand = new Random();
64+
_data.Add(rand.Next().ToString());
65+
_data.Add(rand.Next().ToString());
66+
_data.Add(rand.Next().ToString());
67+
68+
// Does not have the issue if the data is loaded with a delay.
69+
/*
70+
Task.Run(async () =>
71+
{
72+
await Task.Delay(1000);
73+
74+
var rand = new Random();
75+
_data.Add(rand.Next().ToString());
76+
_data.Add(rand.Next().ToString());
77+
_data.Add(rand.Next().ToString());
78+
});
79+
*/
80+
81+
var stackLayout = new StackLayout()
82+
{
83+
Children =
84+
{
85+
new Label()
86+
{
87+
Text = "If you don't see the EmptyView and CollectionView items together the test passed",
88+
Padding = 12,
89+
BackgroundColor = Color.Black,
90+
TextColor = Color.White,
91+
AutomationId = "Instructions"
92+
},
93+
carouselView
94+
}
95+
};
96+
97+
Content = stackLayout;
98+
}
99+
100+
protected override void Init()
101+
{
102+
103+
}
104+
105+
#if UITEST
106+
[Test]
107+
public void EmptyViewAndItemsNotShownTogether()
108+
{
109+
// Wait until the collection view is shown
110+
RunningApp.WaitForElement("TehCollectionView");
111+
112+
RunningApp.Screenshot("CollectionView should be shown with items and no EmptyView");
113+
114+
// Verify that the empty view is not shown
115+
RunningApp.WaitForNoElement("CollectionViewEmptyView");
116+
}
117+
#endif
118+
}
119+
120+
public class MyDataTemplateSelector : DataTemplateSelector
121+
{
122+
public DataTemplate MyCollectionViewDataTemplate { get; set; }
123+
124+
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
125+
{
126+
if (item is MyCollectionView)
127+
{
128+
return MyCollectionViewDataTemplate;
129+
}
130+
131+
return null;
132+
}
133+
}
134+
}
135+

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,11 @@
18611861
<Compile Include="$(MSBuildThisFileDirectory)Issue14805.cs" />
18621862
<Compile Include="$(MSBuildThisFileDirectory)Issue11954.cs" />
18631863
<Compile Include="$(MSBuildThisFileDirectory)Issue13918.xaml.cs" />
1864+
<Compile Include="$(MSBuildThisFileDirectory)Issue13794.cs" />
1865+
<Compile Include="$(MSBuildThisFileDirectory)Controls\MyCollectionView.xaml.cs">
1866+
<DependentUpon>MyCollectionView.xaml</DependentUpon>
1867+
<SubType>Code</SubType>
1868+
</Compile>
18641869
</ItemGroup>
18651870
<ItemGroup>
18661871
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
@@ -2407,6 +2412,10 @@
24072412
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue13918.xaml">
24082413
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
24092414
</EmbeddedResource>
2415+
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Controls\MyCollectionView.xaml">
2416+
<SubType>Designer</SubType>
2417+
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
2418+
</EmbeddedResource>
24102419
</ItemGroup>
24112420
<ItemGroup>
24122421
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla27417Xaml.xaml">
@@ -3013,7 +3022,7 @@
30133022
<ItemGroup>
30143023
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue14801.xaml">
30153024
<SubType>Designer</SubType>
3016-
<Generator>MSBuild:Compile</Generator>
3025+
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
30173026
</EmbeddedResource>
30183027
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue8804.xaml">
30193028
<SubType>Designer</SubType>

Xamarin.Forms.Platform.iOS/CollectionView/ItemsViewController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public abstract class ItemsViewController<TItemsView> : UICollectionViewControll
1717
public TItemsView ItemsView { get; }
1818
protected ItemsViewLayout ItemsViewLayout { get; set; }
1919
bool _initialized;
20-
bool _isEmpty;
20+
bool _isEmpty = true;
2121
bool _emptyViewDisplayed;
2222
bool _disposed;
2323

0 commit comments

Comments
 (0)