From: Gerald Versluis Date: Thu, 18 Jul 2019 02:49:21 +0000 (+0200) Subject: [Bug][iOS] listview / observable collection throwing native error on load (#6576) X-Git-Tag: accepted/tizen/5.5/unified/20200421.150457~232^2^2^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=49d221c3243b0117e384594782fd2cae67cb1276;p=platform%2Fcore%2Fcsapi%2Fxsf.git [Bug][iOS] listview / observable collection throwing native error on load (#6576) * Added reproduction and commented out the misbehaving code * Fixed merge conflicts # Conflicts: # Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems * Implemented UI test * Somehow merged in a non-existing UI test * Removed DetermineEstimatedRowHeight in WillDisplay * Revert "Removed DetermineEstimatedRowHeight in WillDisplay" This reverts commit 431178d923c3bf642aae83331a5dc5b57c4436de. * Removed WillDisplay with DetermineEstimatedRowHeight * Reinstate projitems * Added some more test scenarios * Removed commented code * Update Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6472.cs fixes #6472 --- diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6472.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6472.cs new file mode 100644 index 0000000..cce5fb9 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6472.cs @@ -0,0 +1,179 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using System.Collections.ObjectModel; +using System.Threading.Tasks; + +#if UITEST +using Xamarin.Forms.Core.UITests; +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ +#if UITEST + [Category(UITestCategories.ManualReview)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 6472, "[Bug][iOS] listview / observable collection throwing native error on load", PlatformAffected.iOS)] + public class Issue6472 : TestContentPage + { + const string ListViewAutomationId = "TheListview"; + const string ClearButtonAutomationId = "ClearButton"; + const string UiThreadButtonAutomationId = "UiThreadButton"; + const string OtherThreadButtonAutomationId = "OtherThreadButton"; + const string AddItemsAddRangeButtonAutomationId = "AddItemsAddRangeButton"; + + class testData + { + public int recordId { get; set; } + public string recordText { get; set; } + } + + static class staticData + { + public static ObservableCollection TestCollection = new ObservableCollection(); + public async static void testPopulate() + { + await Task.Run(() => + { + TestCollection.Clear(); + for (int i = 0; i < 11; i++) + { + var tdn = new testData + { + recordId = i, + recordText = i.ToString() + }; + TestCollection.Add(tdn); + } + }); + } + } + + protected override void Init() + { + var clearButton = new Button + { + Text = "Clear collection", + AutomationId = ClearButtonAutomationId + }; + + clearButton.Clicked += (s, a) => + { + staticData.TestCollection.Clear(); + }; + + var buttonAddElementUiThreadButton = new Button + { + Text = "Add item from UI thread", + AutomationId = UiThreadButtonAutomationId + }; + + buttonAddElementUiThreadButton.Clicked += (s, a) => + { + staticData.TestCollection.Add(new testData + { + recordId = 1, + recordText = "Just one" + }); + + staticData.TestCollection.Add(new testData + { + recordId = 2, + recordText = "Just two" + }); + + staticData.TestCollection.Add(new testData + { + recordId = 3, + recordText = "Just three" + }); + }; + + var buttonAddElementOtherThreadButton = new Button + { + Text = "Add item from other thread", + AutomationId = OtherThreadButtonAutomationId + }; + + buttonAddElementOtherThreadButton.Clicked += (s, a) => + { + Task.Run(() => + { + staticData.TestCollection.Add(new testData + { + recordId = 42, + recordText = "THE answer" + }); + + staticData.TestCollection.Add(new testData + { + recordId = 1337, + recordText = "1337 HaxX0r" + }); + }); + }; + + var listView = new ListView + { + ItemTemplate = new DataTemplate(() => + { + var labelAccount = new Label + { + Margin = new Thickness(10, 0), + VerticalTextAlignment = TextAlignment.Center, + HorizontalTextAlignment = TextAlignment.Start, + LineBreakMode = LineBreakMode.NoWrap, + }; + labelAccount.FontSize = 18; + labelAccount.SetBinding(Label.TextProperty, "recordText"); + + var stackAccountLayout = new StackLayout + { + Orientation = StackOrientation.Vertical, + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.StartAndExpand, + Children = { labelAccount } + }; + return new ViewCell { View = stackAccountLayout }; + }), + AutomationId = ListViewAutomationId + }; + + var stack = new StackLayout(); + stack.Children.Add(buttonAddElementOtherThreadButton); + stack.Children.Add(buttonAddElementUiThreadButton); + stack.Children.Add(clearButton); + stack.Children.Add(listView); + + + Content = stack; + listView.ItemsSource = staticData.TestCollection; + } + + protected override void OnAppearing() + { + base.OnAppearing(); + staticData.testPopulate(); + } + +#if UITEST && __IOS__ + [Test] + public void ListViewDoesNotThrowExceptionWithObservableCollection() + { + RunningApp.WaitForElement (ListViewAutomationId); + RunningApp.Screenshot ("We got here without an exception while loading the data and data is visible"); + + RunningApp.Tap(ClearButtonAutomationId); + RunningApp.Tap(UiThreadButtonAutomationId); + RunningApp.Tap(OtherThreadButtonAutomationId); + + RunningApp.Tap(ClearButtonAutomationId); + RunningApp.Tap(OtherThreadButtonAutomationId); + RunningApp.Tap(UiThreadButtonAutomationId); + + } +#endif + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 2b4a008..9e53e7d 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -948,6 +948,7 @@ + diff --git a/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs index 613af35..fbd23fd 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/ListViewRenderer.cs @@ -1173,15 +1173,6 @@ namespace Xamarin.Forms.Platform.iOS List.NotifyRowTapped(indexPath.Section, indexPath.Row, formsCell); } - public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath) - { - if (!_estimatedRowHeight) - { - // Our cell size/estimate is out of date, probably because we moved from zero to one item; update it - DetermineEstimatedRowHeight(); - } - } - public override nint RowsInSection(UITableView tableview, nint section) { int countOverride; @@ -1373,7 +1364,6 @@ namespace Xamarin.Forms.Platform.iOS protected virtual void UpdateEstimatedRowHeight(UITableView tableView) { - // We need to set a default estimated row height, // because re-setting it later(when we have items on the TIL) // will cause the UITableView to reload, and throw an Exception