From b38d590fa4c2347c76c0045c42fe0f803c0b7be5 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Tue, 4 Aug 2020 15:01:35 -0600 Subject: [PATCH] Don't update page offset if not visible (#11602) fixes #10608 --- .../Issue10608.cs | 97 +++++++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 1 + .../Renderers/ShellSectionRenderer.cs | 23 ++++- .../Renderers/PageRenderer.cs | 3 + .../Renderers/ShellSectionRootHeader.cs | 1 + 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue10608.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue10608.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue10608.cs new file mode 100644 index 00000000000..b0782eee5d8 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue10608.cs @@ -0,0 +1,97 @@ +using System.Threading.Tasks; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.Forms.Core.UITests; +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ +#if UITEST + [Category(UITestCategories.Shell)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 10608, "[Bug] [Shell] [iOS] Locked flyout causes application to freezes when quickly switching between tabs", PlatformAffected.iOS)] + public class Issue10608 : TestShell + { + public Issue10608() + { + } + + protected override void Init() + { + FlyoutBehavior = FlyoutBehavior.Locked; + + AddFlyoutItem("Click"); + AddFlyoutItem("Between"); + AddFlyoutItem("These Flyouts"); + AddFlyoutItem("Really Fast"); + AddFlyoutItem("If it doesn't"); + AddFlyoutItem("Lock test has passed"); + + int i = 0; + foreach(var item in Items) + { + item.Items[0].AutomationId = $"FlyoutItem{i}"; + item.Items[0].Items.Add(new ContentPage() + { + Title = "Page" + }); + + i++; + } + + Items.Add(new MenuItem() + { + Text = "Let me click for you", + AutomationId = $"FlyoutItem{i}", + Command = new Command(async () => + { + for (int j = 0; j < 5; j++) + { + CurrentItem = Items[0].Items[0]; + await Task.Delay(10); + CurrentItem = Items[1].Items[0]; + await Task.Delay(10); + } + + CurrentItem = Items[0].Items[0]; + }) + }); + + Items[0].Items[0].Items[0].Title = "Tab 1"; + Items[0].Items[0].Items[0].AutomationId = "Tab1AutomationId"; + Items[1].Items[0].Items[0].Title = "Tab 2"; + Items[1].Items[0].Items[0].AutomationId = "Tab2AutomationId"; + + Items[0].FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems; + Items[1].FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems; + } + +#if UITEST + [Test] + [Category(UITestCategories.Shell)] + public void ShellWithTopTabsFreezesWhenNavigatingFlyoutItems() + { + RunningApp.Tap("FlyoutItem6"); + RunningApp.Tap("FlyoutItem0"); + for (int i = 0; i < 5; i++) + { + RunningApp.WaitForElement("Tab1AutomationId"); + RunningApp.Tap("FlyoutItem0"); + RunningApp.Tap("FlyoutItem1"); + RunningApp.Tap("FlyoutItem0"); + } + + RunningApp.WaitForElement("Tab1AutomationId"); + RunningApp.Tap("FlyoutItem1"); + RunningApp.WaitForElement("Tab2AutomationId"); + RunningApp.Tap("FlyoutItem0"); + RunningApp.WaitForElement("Tab1AutomationId"); + } +#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 ae247acd626..9e3f872af74 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 @@ -1444,6 +1444,7 @@ + diff --git a/Xamarin.Forms.Platform.Android/Renderers/ShellSectionRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ShellSectionRenderer.cs index f0cf37f46f7..61ac5d4398e 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/ShellSectionRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/ShellSectionRenderer.cs @@ -191,6 +191,8 @@ public override AView OnCreateView(LayoutInflater inflater, ViewGroup container, _tablayout.Visibility = ViewStates.Gone; } + _tablayout.LayoutChange += OnTabLayoutChange; + _tabLayoutAppearanceTracker = _shellContext.CreateTabLayoutAppearanceTracker(ShellSection); _toolbarAppearanceTracker = _shellContext.CreateToolbarAppearanceTracker(); @@ -199,6 +201,24 @@ public override AView OnCreateView(LayoutInflater inflater, ViewGroup container, return _rootView = root; } + void OnTabLayoutChange(object sender, AView.LayoutChangeEventArgs e) + { + if (_disposed) + return; + + var items = SectionController.GetItems(); + for (int i = 0; i < _tablayout.TabCount; i++) + { + if (items.Count <= i) + break; + + var tab = _tablayout.GetTabAt(i); + + if(tab.View != null) + FastRenderers.AutomationPropertiesProvider.AccessibilitySettingsChanged(tab.View, items[i]); + } + } + void Destroy() { if (_rootView != null) @@ -210,7 +230,7 @@ void Destroy() _viewPager.Adapter = null; adapter.Dispose(); - + _tablayout.LayoutChange -= OnTabLayoutChange; _toolbarAppearanceTracker.Dispose(); _tabLayoutAppearanceTracker.Dispose(); _toolbarTracker.Dispose(); @@ -267,7 +287,6 @@ protected virtual void OnShellItemPropertyChanged(object sender, PropertyChanged { var newIndex = SectionController.GetItems().IndexOf(ShellSection.CurrentItem); - if (SectionController.GetItems().Count != _viewPager.ChildCount) _viewPager.Adapter.NotifyDataSetChanged(); diff --git a/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs index 149a052a9f0..10cecd4f1f3 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs @@ -396,6 +396,9 @@ void UpdateUseSafeArea() if (!IsPartOfShell && !Forms.IsiOS11OrNewer) return; + if (IsPartOfShell && !_appeared) + return; + var tabThickness = _tabThickness; if (!_isInItems) tabThickness = 0; diff --git a/Xamarin.Forms.Platform.iOS/Renderers/ShellSectionRootHeader.cs b/Xamarin.Forms.Platform.iOS/Renderers/ShellSectionRootHeader.cs index 728c363818c..a650f5d5135 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/ShellSectionRootHeader.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/ShellSectionRootHeader.cs @@ -104,6 +104,7 @@ public override UICollectionViewCell GetCell(UICollectionView collectionView, NS else headerCell.Selected = false; + headerCell.SetAccessibilityProperties(shellContent); return headerCell; }