fix #5518 | Frame Tap Gesture not working when using Visual="Material" in iOS (#7988)
authorKen Nguyen <khuongntrd@gmail.com>
Wed, 4 Dec 2019 16:52:52 +0000 (23:52 +0700)
committerShane Neuville <shneuvil@microsoft.com>
Wed, 4 Dec 2019 16:52:52 +0000 (09:52 -0700)
* fix #5518

* - small changes to ui tests

* - fix automationid and ui test

* - fix null ref

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5518.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Material.iOS/MaterialFrameRenderer.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5518.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5518.cs
new file mode 100644 (file)
index 0000000..9660561
--- /dev/null
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+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
+{
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 5518, "Frame Tap Gesture not working when using Visual=\"Material\" in iOS", PlatformAffected.iOS)]
+       public class Issue5518 : TestContentPage
+       {
+
+               protected override void Init()
+               {
+                       var stack = new StackLayout();
+
+
+                       var frame = new Frame()
+                       {
+                               Visual = VisualMarker.Material,
+                               BackgroundColor = Color.White,
+                               AutomationId = "NoContentFrame"
+                       };
+
+                       var outputLabel1 = new Label() { Text = "", AutomationId = "Output1", HorizontalOptions = LayoutOptions.Center };
+
+                       var tapGestureRecognizer = new TapGestureRecognizer();
+                       tapGestureRecognizer.Tapped += (s, e) =>
+                       {
+                               outputLabel1.Text = "Success";
+                       };
+
+                       frame.GestureRecognizers.Add(tapGestureRecognizer);
+                       stack.Children.Add(frame);
+                       stack.Children.Add(outputLabel1);
+
+                       var frameWithContent = new Frame()
+                       {
+                               Visual = VisualMarker.Material,
+                               Content = new Label() { Text = "I'm label" },
+                               AutomationId = "ContentedFrame"
+                       };
+
+                       var outputLabel2 = new Label() { Text = "", AutomationId = "Output2", HorizontalOptions = LayoutOptions.Center };
+
+                       tapGestureRecognizer = new TapGestureRecognizer();
+                       tapGestureRecognizer.Tapped += (s, e) =>
+                       {
+                               outputLabel2.Text = "Success";
+                       };
+
+                       frameWithContent.GestureRecognizers.Add(tapGestureRecognizer);
+
+                       stack.Children.Add(new Label() { Text = "Clicking each frame should cause `Success` text to appear." });
+                       stack.Children.Add(frameWithContent);
+                       stack.Children.Add(outputLabel2);
+
+                       Content = stack;
+               }
+
+               void TapGestureRecognizer_Tapped(object sender, EventArgs e)
+               {
+                       DisplayAlert("Frame Tap Gesture", "Work", "Ok");
+               }
+
+#if UITEST
+               [Test]
+               public void FrameTapGestureRecognizer()
+               {
+                       RunningApp.WaitForElement("NoContentFrame");
+                       RunningApp.Tap("NoContentFrame");
+                       Assert.AreEqual("Success", RunningApp.WaitForElement("Output1")[0].ReadText());
+
+                       RunningApp.WaitForElement("ContentedFrame");
+                       RunningApp.Tap("I'm label");
+                       Assert.AreEqual("Success", RunningApp.WaitForElement("Output2")[0].ReadText());
+               }
+#endif
+       }
+}
index 83e27ab..e086f61 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)Issue5412.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Helpers\GarbageCollectionHelper.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue4879.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Issue5518.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue5555.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue6458.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue6258.cs" />
index ba78e83..dd6718d 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.ComponentModel;
+using System.Linq;
 using CoreAnimation;
 using CoreGraphics;
 using MaterialComponents;
@@ -18,11 +19,13 @@ namespace Xamarin.Forms.Material.iOS
                float _defaultCornerRadius = -1;
                VisualElementPackager _packager;
                VisualElementTracker _tracker;
+               EventTracker _events;
+
                bool _disposed = false;
 
                public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
                public Frame Element { get; private set; }
-               
+
                public override void WillRemoveSubview(UIView uiview)
                {
                        var content = Element?.Content;
@@ -82,6 +85,9 @@ namespace Xamarin.Forms.Material.iOS
                                        _packager.Load();
 
                                        _tracker = new VisualElementTracker(this);
+
+                                       _events = new EventTracker(this);
+                                       _events.LoadEvents(this);
                                }
 
                                Element.PropertyChanged += OnElementPropertyChanged;
@@ -90,6 +96,12 @@ namespace Xamarin.Forms.Material.iOS
                        }
 
                        OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
+
+                       if (element != null)
+                               element.SendViewInitialized(this);
+
+                       if (!string.IsNullOrEmpty(element?.AutomationId))
+                               AccessibilityIdentifier = element.AutomationId;
                }
 
                protected override void Dispose(bool disposing)
@@ -106,6 +118,9 @@ namespace Xamarin.Forms.Material.iOS
                                _tracker.Dispose();
                                _tracker = null;
 
+                               _events.Dispose();
+                               _events = null;
+                               
                                if (Element != null)
                                {
                                        Element.ClearValue(Platform.iOS.Platform.RendererProperty);
@@ -140,8 +155,21 @@ namespace Xamarin.Forms.Material.iOS
                        if (!Element.HasShadow)
                                SetShadowElevation(0, UIControlState.Normal);
 
-                       // this is set in the theme, so we must always disable it
-                       Interactable = false;
+                       if (Element.GestureRecognizers != null && Element.GestureRecognizers.Any())
+                       {
+                               Interactable = true;
+
+                               // disable ink (ripple) and elevation effect while tapped
+                               InkView.Hidden = true;
+                               if (Element.HasShadow)
+                                       SetShadowElevation(1f, UIControlState.Highlighted);
+                       }
+                       else
+                       {
+                               // this is set in the theme, so we must always disable it               
+                               Interactable = false;
+                       }
+
                }
 
                protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
@@ -234,4 +262,4 @@ namespace Xamarin.Forms.Material.iOS
                void IVisualElementRenderer.SetElementSize(Size size) =>
                        Layout.LayoutChildIntoBoundingRegion(Element, new Rectangle(Element.X, Element.Y, size.Width, size.Height));
        }
-}
\ No newline at end of file
+}