【问题标题】:Xamarin.Forms.Maps how to have a label next to / above pin just like Google Maps?Xamarin.Forms.Maps 如何像谷歌地图一样在图钉旁边/上方有一个标签?
【发布时间】:2021-11-20 23:35:42
【问题描述】:

我想知道当您放大时是否可以在 Xamarin.Forms.Maps 中的图钉上方或旁边显示标签,并且该地点的名称显示在图钉旁边,如下所示:

谷歌地图

iOS

非常感谢!

【问题讨论】:

    标签: c# android ios xamarin.forms xamarin.forms.maps


    【解决方案1】:

    我们可以在每个平台上使用自定义渲染器来做到这一点。

    这里是一个iOS解决方案的例子,只需添加一个子视图并在GetViewForAnnotation 方法中调整它的位置。

    [assembly:ExportRenderer(typeof(CustomMap),typeof(CustomMapRenderer))]
    namespace My_Forms_Test3.iOS
    {
        public class CustomMapRenderer:MapRenderer
        {
            UIView customPinView;
            List<CustomPin> customPins;
            protected override void OnElementChanged(ElementChangedEventArgs<View> e)
            {
                base.OnElementChanged(e);
                if (e.OldElement != null)
                {
                    var nativeMap = Control as MKMapView;
                    nativeMap.GetViewForAnnotation = null;
                    nativeMap.CalloutAccessoryControlTapped -= OnCallourAccessoryControlTapped;
                    nativeMap.DidSelectAnnotationView -= OnDidSelect;
                    nativeMap.DidDeselectAnnotationView -= OnDidDeSelect;
                }
                if (e.NewElement != null)
                {
                    var formsMap = (CustomMap)e.NewElement;
                    var nativeMap = Control as MKMapView;
                    customPins = formsMap.CustomPins;
                    nativeMap.GetViewForAnnotation = GetViewForAnnotation;
                    nativeMap.CalloutAccessoryControlTapped += OnCallourAccessoryControlTapped;
                    nativeMap.DidSelectAnnotationView += OnDidSelect;
                    nativeMap.DidDeselectAnnotationView += OnDidDeSelect;
    
                }
    
            }
    
            private void OnDidDeSelect(object sender, MKAnnotationViewEventArgs e)
            {
                if (!e.View.Selected)
                {
                    customPinView.RemoveFromSuperview();
                    customPinView.Dispose();
                    customPinView = null;
    
                }
               
    
            }
    
            private void OnDidSelect(object sender, MKAnnotationViewEventArgs e)
            {
    
                throw new NotImplementedException();
            }
    
            private void OnCallourAccessoryControlTapped(object sender, MKMapViewAccessoryTappedEventArgs e)
            {
                throw new NotImplementedException();
            }
    
            protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
            {
             
                MKAnnotationView annotationView = null;
            
                if (annotation is MKUserLocation)
                    return null;
                var customPin = GetCustomPin(annotation as MKPointAnnotation);
                if (customPin == null)
                {
                    throw new Exception("not found");
                }
                annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
                if (annotationView == null)
                {
                    annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
                    annotationView.Image = UIImage.FromFile("pin.png");
           
                    annotationView.CalloutOffset = new CGPoint(0, 0);
                    annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
                    annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
                  
                    ((CustomMKAnnotationView)annotationView).Name = customPin.Name;
                    customPinView = new UIView();
                    var Label = new UILabel();
                    Label.Text = "Samsung";
                    Label.Frame=new CGRect(annotationView.GetFrame().X+35,annotationView.GetFrame().Y,100,50);
                    var Label2 = new UILabel();
                    Label2.Text = "20:20";
                    Label2.Frame = new CGRect(annotationView.GetFrame().X + 35, annotationView.GetFrame().Y+20, 100, 50);
                    customPinView.Frame= new CGRect(annotationView.GetFrame().X+40, annotationView.GetFrame().Y-20, 100, 50);
                    customPinView.AddSubview(Label);
                    customPinView.AddSubview(Label2);
                    Label.BaselineAdjustment = UIBaselineAdjustment.AlignBaselines;
                    customPinView.BackgroundColor = UIColor.White;
                    customPinView.Layer.CornerRadius = 5;
                    customPinView.Alpha = (nfloat)0.8;
                    customPinView.Layer.MasksToBounds = true;
                    annotationView.AddSubview(customPinView);
                }
                annotationView.CanShowCallout = true;
             
                return annotationView;
    
            }
    
            CustomPin GetCustomPin(MKPointAnnotation annotation)
            {
                var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
                foreach (var pin in customPins)
                {
                    if (pin.Position == position)
                    { return pin; }
                }
                return null;
    
            }}
    

    请参阅https://stackoverflow.com/a/69265658/8187800

    【讨论】:

    • Cole 你一直在帮助我解决我所有的 Xamarin.Forms 问题已经有一段时间了,你是最棒的,非常感谢,我会尽快尝试并将其标记为答案.
    • 嗨@Jimmy,问题解决了吗?
    • 我没有机会尝试,但我会在几天内尽快尝试
    • 好的,没关系。
    • 所以它并没有真正起作用,我得到了该位置旁边的白色矩形而不是文本,并且我无法使背景透明,是否有自定义渲染器功能让它看起来像官方应用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多