Xamarin.Forms.Maps 在 iOS 模拟器上自定义 pin 加载,但不是物理设备

问题描述

我在使用 Xamarin.Forms.Maps 时遇到问题,并且在 iOS 模拟器上一切正常,我打开地图,从那里导航到自定义图钉,所有这些图钉都显示没有问题,但是当我使用物理设备(iOS 14.6 并且上次更新时也没有工作)时会出现问题。

当我启动应用程序时,一切都一样,但是如果我尝试转到最近的引脚,应用程序会抛出异常 System.NullReferenceException: "Object reference not set to the instance of an object",只有当我尝试在地图上显示多个图钉。

我的应用程序中有一种方法可以将我重定向一个 pin,如果点击它并且有效,它会将我发送到 pin,但如果我缩小应用程序再次中断。 当我调试并在中断它的方法上设置断点时,GetViewForAnnotation 中的 GetCustomPin 方法会引发异常,问题是它不会将参数传递给 GetCustomPin 方法(如果它用于多个引脚)但如果它是一方面(我不知道这是否与当它用于多个引脚时它可能在后台线程上工作这一事实有关)但它适用于 Android,因此它在共享项目代码中不是问题。

代码如下:

[assembly: ExportRenderer(typeof(CustomMap),typeof(CustomMapRenderer))]
namespace App.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 -= OnCalloutAccessoryControlTapped;
            nativeMap.DidSelectAnnotationView -= OnDidSelectAnnotationView;
            nativeMap.DiddeselectAnnotationView -= OnDiddeselectAnnotationView;
        }

        if (e.NewElement != null)
        {
            var formsMap = (CustomMap)e.NewElement;
            var nativeMap = Control as MKMapView;
            customPins = formsMap.CustomPins;
            nativeMap.OverrideUserInterfaceStyle = UIUserInterfaceStyle.Dark;
            //nativeMap.WeakDelegate = this;

            nativeMap.GetViewForAnnotation = GetViewForAnnotation;
            nativeMap.CalloutAccessoryControlTapped += OnCalloutAccessoryControlTapped;
            nativeMap.DidSelectAnnotationView += OnDidSelectAnnotationView;
            nativeMap.DiddeselectAnnotationView += OnDiddeselectAnnotationView;
        }
    }

    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)
        {
            return null;
        }

        annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
        if (annotationView == null)
        {
            ...
            annotationView.CalloutOffset = new CGPoint(0,0);
            annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("icon.png"));
            annotationView.RightCalloutAccessoryView = new UIImageView(UIImage.FromFile("icon.png"));
            ((CustomMKAnnotationView)annotationView).Name = customPin.Name;
            ((CustomMKAnnotationView)annotationView).Url = customPin.Url;
            annotationView.CanShowCallout = true;
        }
        else
        {
            annotationView.Annotation = annotation;
        }

        configureDetailView(annotationView);

        return annotationView;
    }

    void configureDetailView(MKAnnotationView annotationView)
    {
        int width = 350;
        int height = 250;

        var snapshotView = new UIView();
        snapshotView.TranslatesAutoresizingMaskIntoConstraints = false;
        NSDictionary views = NSDictionary.FromObjectAndKey(snapshotView,new Nsstring("snapshotView"));
        snapshotView.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:[snapshotView(250)]",new NSLayoutFormatOptions(),null,views));
        snapshotView.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:[snapshotView(80)]",views));

        var options = new MKMapSnapshotOptions();
        options.Size = new CGSize(width,height);
        options.MapType = MKMapType.SatelliteFlyover;
        options.Camera = MKMapCamera.CameraLookingAtCenterCoordinate(annotationView.Annotation.Coordinate,250,65,0);

        var snapshotter = new MKMapSnapshotter(options);
        snapshotter.Start((snapshot,error) =>
        {
            if (snapshot != null)
            {
                UILabel label = new UILabel();
                UILabel label2 = new UILabel();
                UILabel label3 = new UILabel();
                UILabel label4 = new UILabel();
                //UIButton uIButton = new UIButton(UIButtonType.System);
                //uIButton.SetTitle("Save",UIControlState.normal);

                //uIButton.Frame = new CGRect(200,10,150,15);
                label.Frame = new CGRect(15,20);
                label2.Frame = new CGRect(15,20,210,20);
                label3.Frame = new CGRect(15,40,20);
                label4.Frame = new CGRect(15,60,20);
                // Add your custom controls here
                snapshotView.AddSubviews(label,label2,label3,label4);
            }
        });

        annotationView.DetailCalloutAccessoryView = snapshotView;
    }

    void OnCalloutAccessoryControlTapped(object sender,MKMapViewAccessoryTappedEventArgs e)
    {
        CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
        if (!string.IsNullOrWhiteSpace(customView.Url))
        {
            UIApplication.SharedApplication.OpenUrl(new Foundation.NSUrl(customView.Url));
        }
    }

    void OnDidSelectAnnotationView(object sender,MKAnnotationViewEventArgs e)
    {
        CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
        customPinView = new UIView();

        customPinView.Frame = new CGRect(0,200,84);
        customPinView.Center = new CGPoint(0,-(e.View.Frame.Height + 75));
        e.View.AddSubview(customPinView);
    }

    void OnDiddeselectAnnotationView(object sender,MKAnnotationViewEventArgs e)
    {
        if (!e.View.Selected)
        {
            customPinView.RemoveFromSuperview();
            customPinView.dispose();
            customPinView = null;
        }
    }

    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;
    }
}

}

我不知道如何解决这个问题,谢谢您的帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)