Beispiel #1
0
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            try
            {
                var isHandledOrBubblingInManaged = default(bool);
                foreach (UITouch touch in touches)
                {
                    var id   = NativePointerId.Get(this, touch);
                    var args = new PointerRoutedEventArgs(id.Value, touch, evt, this);

                    isHandledOrBubblingInManaged |= OnNativePointerUp(args);
                    isHandledOrBubblingInManaged |= OnNativePointerExited(args);

                    id.Release(this);
                }

                if (!isHandledOrBubblingInManaged)
                {
                    // Continue native bubbling up of the event
                    base.TouchesEnded(touches, evt);
                }

                NotifyParentTouchesManagersManipulationEnded();
            }
            catch (Exception e)
            {
                Application.Current.RaiseRecoverableUnhandledException(e);
            }
        }
Beispiel #2
0
        public override void TouchesCancelled(NSSet touches, UIEvent evt)
        {
            try
            {
                var isHandledOrBubblingInManaged = default(bool);
                foreach (UITouch touch in touches)
                {
                    var id   = NativePointerId.Get(this, touch);
                    var args = new PointerRoutedEventArgs(id.Value, touch, evt, this);

                    // Note: We should have raise either PointerCaptureLost or PointerCancelled here depending of the reason which
                    //		 drives the system to bubble a lost. However we don't have this kind of information on iOS, and it's
                    //		 usually due to the ScrollView which kicks in. So we always raise the CaptureLost which is the behavior
                    //		 on UWP when scroll starts (even if no capture are actives at this time).

                    isHandledOrBubblingInManaged |= OnNativePointerCancel(args, isSwallowedBySystem: true);

                    id.Release(this);
                }

                if (!isHandledOrBubblingInManaged)
                {
                    // Continue native bubbling up of the event
                    base.TouchesCancelled(touches, evt);
                }

                NotifyParentTouchesManagersManipulationEnded();
            }
            catch (Exception e)
            {
                Application.Current.RaiseRecoverableUnhandledException(e);
            }
        }
Beispiel #3
0
        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            try
            {
                var isHandledOrBubblingInManaged = default(bool);
                foreach (UITouch touch in touches)
                {
                    var id            = NativePointerId.Get(this, touch);
                    var args          = new PointerRoutedEventArgs(id.Value, touch, evt, this);
                    var isPointerOver = touch.IsTouchInView(this);

                    // As we don't have enter/exit equivalents on iOS, we have to update the IsOver on each move
                    // Note: Entered / Exited are raised *before* the Move (Checked using the args timestamp)
                    isHandledOrBubblingInManaged |= OnNativePointerMoveWithOverCheck(args, isPointerOver);
                }

                if (!isHandledOrBubblingInManaged)
                {
                    // Continue native bubbling up of the event
                    base.TouchesMoved(touches, evt);
                }
            }
            catch (Exception e)
            {
                Application.Current.RaiseRecoverableUnhandledException(e);
            }
        }
Beispiel #4
0
            public static NativePointerId Get(UIElement element, UITouch touch)
            {
                if (!_instances.TryGetValue(touch.Handle, out var id))
                {
                    _instances[touch.Handle] = id = new NativePointerId(touch.Handle);
                }

                id._leases.Add(element);

                return(id);
            }
Beispiel #5
0
        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            if (IsPointersSuspended)
            {
                return;                 // Will also prevent subsequents events
            }

            /* Note: Here we have a mismatching behavior with UWP, if the events bubble natively we're going to get
             *               (with Ctrl_02 is a child of Ctrl_01):
             *                              Ctrl_02: Entered
             *                                               Pressed
             *                              Ctrl_01: Entered
             *                                               Pressed
             *
             *              While on UWP we will get:
             *                              Ctrl_02: Entered
             *                              Ctrl_01: Entered
             *                              Ctrl_02: Pressed
             *                              Ctrl_01: Pressed
             *
             *              However, to fix this is would mean that we handle all events in managed code, but this would
             *              break lots of control (ScrollViewer) and ability to easily integrate an external component.
             */

            try
            {
                NotifyParentTouchesManagersManipulationStarted();

                var isHandledOrBubblingInManaged = default(bool);
                foreach (UITouch touch in touches)
                {
                    var id   = NativePointerId.Get(this, touch);
                    var args = new PointerRoutedEventArgs(id.Value, touch, evt, this);

                    isHandledOrBubblingInManaged |= OnNativePointerEnter(args);
                    isHandledOrBubblingInManaged |= OnNativePointerDown(args);
                }

                /*
                 * **** WARNING ****
                 *
                 * If we do not propagate the "TouchesBegan" to the parents, they won't receive the
                 * "TouchesMoved" nor the "TouchesEnded".
                 *
                 * It means that if a control (like the Button) handles the "Pressed" (or the "Entered")
                 * parent won't receive any touch event. As it doesn't seems to be have any impact in application,
                 * it's accepted as a known limitation.
                 *
                 * There is 2 ways to fix this:
                 *  - Still propagate the native "TouchesBegan" and then in parents control filter out events
                 *	  that was already raised in managed
                 *  - Keep a track in local element that the "TouchesBegan" was handled in managed, and then raise
                 *    all subsequent "Move", "Released" and "Exited" in managed only.
                 */

                if (!isHandledOrBubblingInManaged)
                {
                    // Continue native bubbling up of the event
                    base.TouchesBegan(touches, evt);
                }
            }
            catch (Exception e)
            {
                Application.Current.RaiseRecoverableUnhandledException(e);
            }
        }