1

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

当我启动应用程序时,一切正常,但是如果我尝试转到最近的引脚,应用程序会抛出异常 System.NullReferenceException:“对象引用未设置为对象的实例”,只有当我尝试显示多个引脚时在地图上。

我的应用程序中有一个方法,如果单击它可以将我重定向到一个图钉并且有效,它会将我发送到图钉,但如果我缩小应用程序会再次中断。当我调试并在中断的方法处设置断点时,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)]", new NSLayoutFormatOptions(), null, 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, 0, 150, 20);
                label2.Frame = new CGRect(15, 20, 210, 20);
                label3.Frame = new CGRect(15, 40, 210, 20);
                label4.Frame = new CGRect(15, 60, 210, 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, 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;
    }
}

}

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

4

0 回答 0