Xamarin.forms xamarin forms maps中的长攻丝和插针

Xamarin.forms xamarin forms maps中的长攻丝和插针,xamarin.forms,maps,xamarin.forms.maps,Xamarin.forms,Maps,Xamarin.forms.maps,我使用了Xamarin.Forms.Maps nuget包并在设备上显示了地图。我能够在下面代码的帮助下在外部按钮点击上显示pin,但无法在地图点击上在特定位置放置pin public void addPin(double latitude, double longitude, string labelName) { Position position = new Position(latitude, longitude); _assignedPin = new Pin

我使用了Xamarin.Forms.Maps nuget包并在设备上显示了地图。我能够在下面代码的帮助下在外部按钮点击上显示pin,但无法在地图点击上在特定位置放置pin

public void addPin(double latitude, double longitude, string labelName)
{
     Position position = new Position(latitude, longitude);
    _assignedPin = new Pin
    {
        Type = PinType.Place,
        Position = position,
        Label = labelName,
        Address = "custom detail info"
    };
    map.Pins.Add(_assignedPin);
}

我随后在map上获得lat long,但map不会在map上显示pin。

我们需要使用xamarin.forms.maps将渲染器本身中的代码添加到drop pin中

在Android:Renderer类中:

private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
    Map.Pins.Add(new Pin
    {
        Label = "Pin from tap",
        Position = new Position(e.Point.Latitude, e.Point.Longitude))
    }
}
[assembly: ExportRenderer(typeof(ExtMap), typeof(ExtMapRenderer))]
namespace Xamarin.iOS.CustomRenderers
{
    /// <summary>
    /// Renderer for the xamarin ios map control
    /// </summary>
    public class ExtMapRenderer : MapRenderer
    {
        private readonly UITapGestureRecognizer _tapRecogniser;

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

        protected override IMKAnnotation CreateAnnotation(Pin pin)
        {
            return base.CreateAnnotation(pin);
        }



        class BasicMapAnnotation : MKAnnotation
        {
            CLLocationCoordinate2D coord;
            string title, subtitle;

            public override CLLocationCoordinate2D Coordinate { get { return coord; } }
            public override void SetCoordinate(CLLocationCoordinate2D value)
            {
                coord = value;
            }
            public override string Title { get { return title; } }
            public override string Subtitle { get { return subtitle; } }
            public BasicMapAnnotation(CLLocationCoordinate2D coordinate, string title, string subtitle)
            {
                this.coord = coordinate;
                this.title = title;
                this.subtitle = subtitle;
            }
        }



        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
        }

        private async void OnTap(UITapGestureRecognizer recognizer)
        {
            var cgPoint = recognizer.LocationInView(Control);
            var nativeMap = Control as MKMapView;

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

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

            try
            {
                var lat = location.Latitude;
                var lon = location.Longitude;

                var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);

                var placemark = placemarks?.FirstOrDefault();
                if (placemark != null)
                {
                    var geocodeAddress =
                        $"AdminArea:       {placemark.AdminArea}\n" +
                        $"CountryCode:     {placemark.CountryCode}\n" +
                        $"CountryName:     {placemark.CountryName}\n" +
                        $"FeatureName:     {placemark.FeatureName}\n" +
                        $"Locality:        {placemark.Locality}\n" +
                        $"PostalCode:      {placemark.PostalCode}\n" +
                        $"SubAdminArea:    {placemark.SubAdminArea}\n" +
                        $"SubLocality:     {placemark.SubLocality}\n" +
                        $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
                        $"Thoroughfare:    {placemark.Thoroughfare}\n";

                    Console.WriteLine(geocodeAddress);
                    var annotation = new BasicMapAnnotation(new CLLocationCoordinate2D(lat, lon), placemark.Thoroughfare, placemark.SubThoroughfare);
                    nativeMap.AddAnnotation(annotation);
                }
            }
            catch (FeatureNotSupportedException fnsEx)
            {
                // Feature not supported on device
                Console.WriteLine(fnsEx);
            }
            catch (Exception ex)
            {
                // Handle exception that may have occurred in geocoding
                Console.WriteLine(ex);
            }




        }

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

            base.OnElementChanged(e);

            if (Control != null)
                Control.AddGestureRecognizer(_tapRecogniser);
        }
    }
}
在iOS渲染器类中:

private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
    Map.Pins.Add(new Pin
    {
        Label = "Pin from tap",
        Position = new Position(e.Point.Latitude, e.Point.Longitude))
    }
}
[assembly: ExportRenderer(typeof(ExtMap), typeof(ExtMapRenderer))]
namespace Xamarin.iOS.CustomRenderers
{
    /// <summary>
    /// Renderer for the xamarin ios map control
    /// </summary>
    public class ExtMapRenderer : MapRenderer
    {
        private readonly UITapGestureRecognizer _tapRecogniser;

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

        protected override IMKAnnotation CreateAnnotation(Pin pin)
        {
            return base.CreateAnnotation(pin);
        }



        class BasicMapAnnotation : MKAnnotation
        {
            CLLocationCoordinate2D coord;
            string title, subtitle;

            public override CLLocationCoordinate2D Coordinate { get { return coord; } }
            public override void SetCoordinate(CLLocationCoordinate2D value)
            {
                coord = value;
            }
            public override string Title { get { return title; } }
            public override string Subtitle { get { return subtitle; } }
            public BasicMapAnnotation(CLLocationCoordinate2D coordinate, string title, string subtitle)
            {
                this.coord = coordinate;
                this.title = title;
                this.subtitle = subtitle;
            }
        }



        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
        }

        private async void OnTap(UITapGestureRecognizer recognizer)
        {
            var cgPoint = recognizer.LocationInView(Control);
            var nativeMap = Control as MKMapView;

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

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

            try
            {
                var lat = location.Latitude;
                var lon = location.Longitude;

                var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);

                var placemark = placemarks?.FirstOrDefault();
                if (placemark != null)
                {
                    var geocodeAddress =
                        $"AdminArea:       {placemark.AdminArea}\n" +
                        $"CountryCode:     {placemark.CountryCode}\n" +
                        $"CountryName:     {placemark.CountryName}\n" +
                        $"FeatureName:     {placemark.FeatureName}\n" +
                        $"Locality:        {placemark.Locality}\n" +
                        $"PostalCode:      {placemark.PostalCode}\n" +
                        $"SubAdminArea:    {placemark.SubAdminArea}\n" +
                        $"SubLocality:     {placemark.SubLocality}\n" +
                        $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
                        $"Thoroughfare:    {placemark.Thoroughfare}\n";

                    Console.WriteLine(geocodeAddress);
                    var annotation = new BasicMapAnnotation(new CLLocationCoordinate2D(lat, lon), placemark.Thoroughfare, placemark.SubThoroughfare);
                    nativeMap.AddAnnotation(annotation);
                }
            }
            catch (FeatureNotSupportedException fnsEx)
            {
                // Feature not supported on device
                Console.WriteLine(fnsEx);
            }
            catch (Exception ex)
            {
                // Handle exception that may have occurred in geocoding
                Console.WriteLine(ex);
            }




        }

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

            base.OnElementChanged(e);

            if (Control != null)
                Control.AddGestureRecognizer(_tapRecogniser);
        }
    }
}
[程序集:ExportRenderer(typeof(ExtMap),typeof(extmaprederer))]
命名空间Xamarin.iOS.CustomRenders
{
/// 
///xamarin ios映射控件的渲染器
/// 
公共类ExtMapRenderer:MapRenderer
{
专用只读UITapGestureRecognizer\u TapRecognizer;
公共ExtMapRenderer()
{
_TapRecognizer=新的UITapGestureRecognizer(OnTap)
{
NumberOfTapsRequired=1,
NumberOfTouchesRequired=1
};
}
受保护的覆盖IMKAnnotation CreateAnnotation(Pin)
{
返回base.CreateAnnotation(pin);
}
类BasicManotation:MKAnnotation
{
CLLocationCoordinate2D coord;
字符串标题、副标题;
公共重写CLLocationCoordinate2D坐标{get{return coord;}}
公共覆盖无效SetCoordinate(CLLocationCoordinate2D值)
{
坐标=价值;
}
公共重写字符串标题{get{return Title;}}
公共重写字符串字幕{get{return Subtitle;}}
公共基本符号(CLLocationCoordinate2D坐标、字符串标题、字符串副标题)
{
this.coord=坐标;
this.title=标题;
this.subtitle=副标题;
}
}
受保护的覆盖无效OnElementPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送方,e);
}
专用异步void OnTap(UITapGestureRecognitor识别器)
{
var cgPoint=识别器。位置视图(控制);
var nativeMap=作为MKMapView的控件;
变量位置=((MKMapView)控件).ConvertPoint(cgPoint,控件);
((ExtMap)元素).OnTap(新位置(location.Latitude,location.Longitude));
尝试
{
var lat=位置、纬度;
var lon=位置。经度;
var placemarks=await Geocoding.GetPlacemarksAsync(lat,lon);
var placemark=placemarks?.FirstOrDefault();
if(placemark!=null)
{
地理编码地址=
$“AdminArea:{placemark.AdminArea}\n”+
$“CountryCode:{placemark.CountryCode}\n”+
$“CountryName:{placemark.CountryName}\n”+
$“FeatureName:{placemark.FeatureName}\n”+
$“位置:{placemark.Locality}\n”+
$“PostalCode:{placemark.PostalCode}\n”+
$“SubAdminArea:{placemark.SubAdminArea}\n”+
$“子局部性:{placemark.SubLocality}\n”+
$“次通道:{placemark.subthoroughe}\n”+
$“通道:{placemark.thoroughure}\n”;
控制台写入线(地理编码地址);
var注释=新的BasicPannotation(新的CLLocationCoordinate2D(纬度、经度)、placemark.大道、placemark.亚大道);
nativeMap.AddAnnotation(注释);
}
}
捕获(功能不支持异常fnsEx)
{
//设备上不支持此功能
控制台写入线(fnsEx);
}
捕获(例外情况除外)
{
//处理地理编码中可能发生的异常
控制台写入线(ex);
}
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
if(控件!=null)
Control.RemoveGestureRecognizer(_-TapRecognizer);
基础。一个要素发生变化(e);
if(控件!=null)
Control.AddGestureRecognizer(_-TapRecognizer);
}
}
}

Hi,这个博客是基于自定义渲染器来显示地图的。你在安卓或IOS中测试它的设备。我从安卓开始。我用Android解决了这个问题。需要在iOS中测试并确认。之后我会发布我自己的答案。太好了!更新答案并记住标记后。^^