Reputation: 3660
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
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