From 42a3faa4110544d7538a9dfd1aa6213a72926541 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Tue, 26 Jan 2021 12:16:39 -0600 Subject: [PATCH] Fix NRE when using Custom Slide Transition (#13494) fixes #13390 * Fix NRE when using Custom Slide Transition * - virtual --- .../CustomRenderers.cs | 20 ++++++++++ .../Issue13390.cs | 40 +++++++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 1 + .../Renderers/ShellFlyoutRenderer.cs | 6 +-- .../Renderers/SlideFlyoutTransition.cs | 15 +++++-- 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13390.cs diff --git a/Xamarin.Forms.ControlGallery.iOS/CustomRenderers.cs b/Xamarin.Forms.ControlGallery.iOS/CustomRenderers.cs index 962f71b9b5f..bf97c35914b 100644 --- a/Xamarin.Forms.ControlGallery.iOS/CustomRenderers.cs +++ b/Xamarin.Forms.ControlGallery.iOS/CustomRenderers.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using CoreGraphics; using CoreLocation; using Foundation; using MapKit; @@ -25,8 +26,27 @@ [assembly: ExportRenderer(typeof(Issue1683.EntryKeyboardFlags), typeof(EntryRendererKeyboardFlags))] [assembly: ExportRenderer(typeof(Issue1683.EditorKeyboardFlags), typeof(EditorRendererKeyboardFlags))] [assembly: ExportRenderer(typeof(Issue5830.ExtendedEntryCell), typeof(ExtendedEntryCellRenderer))] +[assembly: ExportRenderer(typeof(Issue13390), typeof(Issue13390Renderer))] namespace Xamarin.Forms.ControlGallery.iOS { + public class Issue13390Renderer : ShellRenderer + { + protected override IShellFlyoutRenderer CreateFlyoutRenderer() + { + return new ShellFlyoutRenderer() + { + FlyoutTransition = new SlideFlyoutTransition2() + }; + } + + public class SlideFlyoutTransition2 : IShellFlyoutTransition + { + public void LayoutViews(CGRect bounds, nfloat openPercent, UIView flyout, UIView shell, FlyoutBehavior behavior) + { + flyout.Frame = new CGRect(0, 0, 0, 0); + } + } + } public class CustomIOSMapRenderer : ViewRenderer { diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13390.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13390.cs new file mode 100644 index 00000000000..b10c099d05b --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue13390.cs @@ -0,0 +1,40 @@ +using System.Linq; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +using Xamarin.Forms.Core.UITests; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 13390, "Custom SlideFlyoutTransition is not working", + PlatformAffected.iOS)] +#if UITEST + [NUnit.Framework.Category(UITestCategories.Shell)] +#endif + public class Issue13390 : TestShell + { + protected override void Init() + { + CreateContentPage() + .Content = new Label() + { + Text = "If app has not crashed test has passed", + AutomationId = "Success" + }; + } + +#if UITEST && __IOS__ + [Test] + public void CustomSlideFlyoutTransitionCausesCrash() + { + RunningApp.WaitForElement("Success"); + } +#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 53b67b1114b..a9625cbc6a6 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 @@ -1706,6 +1706,7 @@ + diff --git a/Xamarin.Forms.Platform.iOS/Renderers/ShellFlyoutRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/ShellFlyoutRenderer.cs index 09ae6058453..92c53fcb9ff 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/ShellFlyoutRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/ShellFlyoutRenderer.cs @@ -22,11 +22,9 @@ void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) { _backdropBrush = appearance.FlyoutBackdrop; - if (appearance.FlyoutHeight != SlideFlyoutTransition.Height || - appearance.FlyoutWidth != SlideFlyoutTransition.Width) + if (SlideFlyoutTransition?.UpdateFlyoutSize(appearance.FlyoutHeight, appearance.FlyoutWidth) == + true) { - SlideFlyoutTransition?.SetFlyoutSizes(appearance.FlyoutHeight, appearance.FlyoutWidth); - if(_layoutOccured) LayoutSidebar(false, true); } diff --git a/Xamarin.Forms.Platform.iOS/Renderers/SlideFlyoutTransition.cs b/Xamarin.Forms.Platform.iOS/Renderers/SlideFlyoutTransition.cs index 75f11b9a5d3..482ceab7bba 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/SlideFlyoutTransition.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/SlideFlyoutTransition.cs @@ -9,13 +9,20 @@ public class SlideFlyoutTransition : IShellFlyoutTransition internal double Height { get; private set; } = -1d; internal double Width { get; private set; } = -1d; - internal void SetFlyoutSizes(double height, double width) + public virtual bool UpdateFlyoutSize(double height, double width) { - Height = height; - Width = width; + if (Height != height || + Width != width) + { + Height = height; + Width = width; + return true; + } + + return false; } - public void LayoutViews(CGRect bounds, nfloat openPercent, UIView flyout, UIView shell, FlyoutBehavior behavior) + public virtual void LayoutViews(CGRect bounds, nfloat openPercent, UIView flyout, UIView shell, FlyoutBehavior behavior) { if (behavior == FlyoutBehavior.Locked) openPercent = 1;