[iOS] Add ability to turn off updates to native controls from another thread (#3774)
authorSamantha Houts <samhouts@users.noreply.github.com>
Thu, 4 Oct 2018 21:58:34 +0000 (14:58 -0700)
committerGitHub <noreply@github.com>
Thu, 4 Oct 2018 21:58:34 +0000 (14:58 -0700)
* [iOS] Add ability to turn off updates to native controls from another thread

* Flip evaluation order

fixes #1755

Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/Application.cs
Xamarin.Forms.Platform.iOS/VisualElementTracker.cs

index afd7ea2..a64a821 100644 (file)
@@ -4,6 +4,7 @@
 
        public static class Application
        {
+               #region PanGestureRecognizerShouldRecognizeSimultaneously
                public static readonly BindableProperty PanGestureRecognizerShouldRecognizeSimultaneouslyProperty = BindableProperty.Create("PanGestureRecognizerShouldRecognizeSimultaneously", typeof(bool), typeof(Application), false);
 
                public static bool GetPanGestureRecognizerShouldRecognizeSimultaneously(BindableObject element)
                        SetPanGestureRecognizerShouldRecognizeSimultaneously(config.Element, value);
                        return config;
                }
+               #endregion
+
+               #region HandleControlUpdatesOnMainThread
+               public static readonly BindableProperty HandleControlUpdatesOnMainThreadProperty = BindableProperty.Create("HandleControlUpdatesOnMainThread", typeof(bool), typeof(Application), false);
+
+               public static bool GetHandleControlUpdatesOnMainThread(BindableObject element)
+               {
+                       return (bool)element.GetValue(HandleControlUpdatesOnMainThreadProperty);
+               }
+
+               public static void SetHandleControlUpdatesOnMainThread(BindableObject element, bool value)
+               {
+                       element.SetValue(HandleControlUpdatesOnMainThreadProperty, value);
+               }
+
+               public static bool GetHandleControlUpdatesOnMainThread(this IPlatformElementConfiguration<iOS, FormsElement> config)
+               {
+                       return GetHandleControlUpdatesOnMainThread(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<iOS, FormsElement> SetHandleControlUpdatesOnMainThread(this IPlatformElementConfiguration<iOS, FormsElement> config, bool value)
+               {
+                       SetHandleControlUpdatesOnMainThread(config.Element, value);
+                       return config;
+               }
+               #endregion
        }
 }
index e2b1a85..0c278ce 100644 (file)
@@ -5,6 +5,7 @@ using System.Threading;
 using CoreAnimation;
 using Xamarin.Forms.Internals;
 #if __MOBILE__
+using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
 
 namespace Xamarin.Forms.Platform.iOS
 #else
@@ -32,14 +33,12 @@ namespace Xamarin.Forms.Platform.MacOS
 
                public VisualElementTracker(IVisualElementRenderer renderer)
                {
-                       if (renderer == null)
-                               throw new ArgumentNullException("renderer");
+                       Renderer = renderer ?? throw new ArgumentNullException("renderer");
 
                        _propertyChangedHandler = HandlePropertyChanged;
                        _sizeChangedEventHandler = HandleSizeChanged;
                        _batchCommittedHandler = HandleRedrawNeeded;
 
-                       Renderer = renderer;
                        renderer.ElementChanged += OnRendererElementChanged;
                        SetElement(null, renderer.Element);
                }
@@ -143,9 +142,9 @@ namespace Xamarin.Forms.Platform.MacOS
 #if !__MOBILE__
                        var viewParent = view.RealParent as VisualElement;
                        var parentBoundsChanged = _lastParentBounds != (viewParent == null ? Rectangle.Zero : viewParent.Bounds);
+#else
+                       var thread = !boundsChanged && !caLayer.Frame.IsEmpty && Application.Current?.OnThisPlatform()?.GetHandleControlUpdatesOnMainThread() == false;
 #endif
-                       var thread = !boundsChanged && !caLayer.Frame.IsEmpty;
-
                        var anchorX = (float)view.AnchorX;
                        var anchorY = (float)view.AnchorY;
                        var translationX = (float)view.TranslationX;
@@ -165,7 +164,7 @@ namespace Xamarin.Forms.Platform.MacOS
 
                        var updateTarget = Interlocked.Increment(ref _updateCount);
 
-                       Action update = () =>
+                       void update()
                        {
                                if (updateTarget != _updateCount)
                                        return;
@@ -262,7 +261,7 @@ namespace Xamarin.Forms.Platform.MacOS
 
                                transform = transform.Rotate(rotation * (float)Math.PI / 180.0f, 0.0f, 0.0f, 1.0f);
                                caLayer.Transform = transform;
-                       };
+                       }
 
 #if __MOBILE__
                        if (thread)
@@ -324,4 +323,4 @@ namespace Xamarin.Forms.Platform.MacOS
                        Performance.Stop(reference);
                }
        }
-}
\ No newline at end of file
+}