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

[iOS] Fixed NRE removing cells on ListView #13012

Merged
merged 6 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8" ?>
<controls:TestContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:controls="clr-namespace:Xamarin.Forms.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Xamarin.Forms.Controls.Issues.Issue11381"
Title="Issue 11381">
<Grid RowDefinitions="Auto,Auto, *">
<Label
Grid.Row="0"
Padding="12"
BackgroundColor="Black"
TextColor="White"
Text="Tap on image with red background to remove a cell. Repeat for all cells. Without crash, the test has passed."/>
<Label
Grid.Row="1"
AutomationId="ResultId"
x:Name="ItemsCount"/>
<ListView
Grid.Row="2"
AutomationId="ListViewId"
x:Name="Issue11381ListView"
GroupDisplayBinding="{Binding LongName}"
GroupShortNameBinding="{Binding ShortName}"
HasUnevenRows="True"
IsGroupingEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Label
FontSize="Large"
Text="{Binding Name}" />
<Label
Text="{Binding Comment}" />
<Image
Aspect="AspectFit"
BackgroundColor="Red"
HeightRequest="40"
Source="https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1Mu3b?ver=5c31" />
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapGestureRecognizerTapped" />
</StackLayout.GestureRecognizers>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</controls:TestContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using System.Linq;

#if UITEST
using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ListView)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 11381, "[Bug] [iOS] NRE on grouped ListView when removing cells with gesture recognizers",
PlatformAffected.iOS)]
public partial class Issue11381 : TestContentPage
{
public Issue11381()
{
#if APP
InitializeComponent();

grouped = new ObservableCollection<GroupedIssue11381Model> ();

var g1Group = new GroupedIssue11381Model () { LongName = "Group1", ShortName="g1" };
var g2Group = new GroupedIssue11381Model () { LongName = "Group2", ShortName = "g2" };

g1Group.Add (new Issue11381Model () { Name = "G1I1", IsReallyAVeggie = true, Comment = "Lorem ipsum dolor sit amet" });
g1Group.Add (new Issue11381Model () { Name = "G1I2", IsReallyAVeggie = false, Comment = "Lorem ipsum dolor sit amet" });
g1Group.Add (new Issue11381Model () { Name = "G1I3", IsReallyAVeggie = true, Comment = "Lorem ipsum dolor sit amet" });
g1Group.Add (new Issue11381Model () { Name = "G1I4", IsReallyAVeggie = true, Comment = "Lorem ipsum dolor sit amet" });

g2Group.Add (new Issue11381Model () {Name = "G2I1", IsReallyAVeggie = false,Comment = "Lorem ipsum dolor sit amet" });
g2Group.Add (new Issue11381Model () {Name = "G2I2", IsReallyAVeggie = false,Comment = "Lorem ipsum dolor sit amet" });

grouped.Add (g1Group); grouped.Add (g2Group);

Issue11381ListView.ItemsSource = grouped;
#endif
}

public ObservableCollection<GroupedIssue11381Model> grouped { get; set; }

protected override void Init()
{

}

#if APP
void OnTapGestureRecognizerTapped(object sender, EventArgs e)
{
if (sender is View view && view.BindingContext is Issue11381Model model)
{
var group = grouped.FirstOrDefault(g => g.Contains(model));

if (group != null)
{
group.Remove(model);

if (!group.Any())
{
grouped.Remove(group);
}

ItemsCount.Text = $"{grouped.Count} groups";
}
}
}
#endif

#if UITEST
[Test]
public void Issue11381RemoveListViewGroups()
{
RunningApp.WaitForElement("ListViewId", "Timed out waiting for the ListView.");

RunningApp.Tap(x => x.Marked("G1I1"));
RunningApp.Tap(x => x.Marked("G1I2"));
RunningApp.Tap(x => x.Marked("G1I3"));
RunningApp.Tap(x => x.Marked("G1I4"));
RunningApp.Tap(x => x.Marked("G2I1"));
RunningApp.Tap(x => x.Marked("G2I2"));

RunningApp.WaitForElement("ResultId");
Assert.AreEqual("0 groups", RunningApp.WaitForElement("ResultId")[0].ReadText());
}
#endif
}

[Preserve(AllMembers = true)]
public class Issue11381Model
{
public string Name { get; set; }
public string Comment { get; set; }
public bool IsReallyAVeggie { get; set; }
public string Image { get; set; }
}

[Preserve(AllMembers = true)]
public class GroupedIssue11381Model : ObservableCollection<Issue11381Model>
{
public string LongName { get; set; }
public string ShortName { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue8988.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12084.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12512.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11381.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12685.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12642.cs" />
</ItemGroup>
Expand Down Expand Up @@ -2005,6 +2006,9 @@
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue12084.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue11381.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla27417Xaml.xaml">
Expand Down
2 changes: 1 addition & 1 deletion Xamarin.Forms.Platform.iOS/EventTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ void LoadRecognizers()
continue;

var nativeRecognizer = GetNativeRecognizer(recognizer);
if (nativeRecognizer != null)
if (nativeRecognizer != null && _handler != null)
{
#if __MOBILE__
nativeRecognizer.ShouldReceiveTouch = _shouldReceiveTouch;
Expand Down