OrcusZ
OrcusZ

Reputation: 3660

Xamarin Forms Map Tap Gesture IOS

I implement a custom renderer for Xamarin Forms Map to implement a Tap Event.

I the PCL I have this code :

public class ExtMap : Map
    {
        /// <summary>
        /// Event thrown when the user taps on the map
        /// </summary>
        public event EventHandler<MapTapEventArgs> Tapped;

        #region Constructors

        /// <summary>
        /// Default constructor
        /// </summary>
        public ExtMap()
        {

        }

        /// <summary>
        /// Constructor that takes a region
        /// </summary>
        /// <param name="region"></param>
        public ExtMap(MapSpan region)
            : base(region)
        {

        }

        #endregion

        public void OnTap(Position coordinate)
        {
            OnTap(new MapTapEventArgs { Position = coordinate });
        }

        protected virtual void OnTap(MapTapEventArgs e)
        {
            var handler = Tapped;

            if (handler != null)
                handler(this, e);
        }
    }

And in my IOS Project this code :

public class ExtMapRenderer : MapRenderer
    {
        private readonly UITapGestureRecognizer _tapRecogniser;

        public ExtMapRenderer()
        {
            _tapRecogniser = new UITapGestureRecognizer(OnTap)
            {
                NumberOfTapsRequired = 1,
                NumberOfTouchesRequired = 1
            };
        }

        private void OnTap(UITapGestureRecognizer recognizer)
        {
            var cgPoint = recognizer.LocationInView(Control);

            var location = ((MKMapView)Control).ConvertPoint(cgPoint, Control);

            ((ExtMap)Element).OnTap(new Position(location.Latitude, location.Longitude));
        }

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            if (Control != null)
                Control.RemoveGestureRecognizer(_tapRecogniser);

            base.OnElementChanged(e);

            if (Control != null)
            {
                var nativeMap = Control as MKMapView;
                nativeMap.ShowsUserLocation = true;
                Control.AddGestureRecognizer(_tapRecogniser);
            }

        }
    }

In the simulator sometimes the event is raised, but I have to click randomly a lot of time in the map. In my iPhone, the event is never raised.

In Android phone & Emulator, the event is working correctly so I suspect a bad implementation in IOS Project but I do not know how I can improve it.

Upvotes: 0

Views: 650

Answers (1)

Steve Chadbourne
Steve Chadbourne

Reputation: 6953

I have an iOS map renderer where tap is working correctly.

My OnElementChanged is a bit different to yours:

private MKMapView Map => Control as MKMapView;

protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null && Map != null)
    {
        Control?.RemoveGestureRecognizer(_tapRecogniser);
    }

    if (e.NewElement != null)
    {
        Control?.AddGestureRecognizer(_tapRecogniser);
    }
}

Upvotes: 1

Related Questions