从不调用GetViewForAnnotation

时间:2015-10-07 11:33:55

标签: xamarin xamarin.ios mkannotationview mkmapviewdelegate

我正在创建一个MapView,我想在其中显示一些自定义注释。

因此,我认为您通常使用IMKAnnotation方法向MKMapView添加一些AddAnnotation。我确保在主线程上调用它,如:

new NSObject().InvokeOnMainThread(() => {
    _mapView.AddAnnotation(myNewAnnotation);
});

在添加这些之后,我确实看到MKMapView现在包含我在使用调试器检查时在Annotations属性中添加的所有注释。

然而,问题是GetViewForAnnotation永远不会被调用,无论我怎么做。

我试过了:

_mapView.GetViewForAnnotation += ViewForAnnotation;

private MKAnnotationView ViewForAnnotation(MKMapView mapView, IMKAnnotation annotation) {
    // do stuff here
}

我尝试过实施自己的代表:

public class MyMapViewDelegate : MKMapViewDelegate
{
    public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation) {
        // do stuff
    }
}

_delegate = new MyMapViewDelegate();
_mapView.Delegate = _delegate;

我已尝试使用WeakDelegate

public class MapView : ViewController, IMKMapViewDelegate
{
    private MKMapView _mapView;

    public override void ViewDidLoad() {
        _mapView = new MKMapView();
        _mapView.WeakDelegate = this;
    }

    [Export("mapView:viewForAnnotation:")]
    public MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation) {
        // do stuff
    }
}

似乎没有触发GetViewForAnnotation方法。我有什么想法吗?

修改

详细了解我现在的情况。

[Register("MapView")]
public class MapView : MvxViewController<MapViewModel>
{
    private MKMapView _mapView;
    private NMTAnnotationManager _annotationManager;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        _mapView = new MKMapView();
        _mapView.GetViewForAnnotation += GetViewForAnnotation;
        _annotationManager = new NMTAnnotationManager(_mapView);

        var bindSet = this.CreateBindingSet<MapView, MapViewModel>();
        bindSet.Bind(_annotationManager).For(a => a.ItemsSource).To(vm => vm.Locations).OneWay();
        bindSet.Apply();

        Add(_mapView);

        View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

        View.AddConstraints(
            _mapView.AtTopOf(View),
            _mapView.AtLeftOf(View),
            _mapView.AtRightOf(View),
            _mapView.AtBottomOf(View));
    }

    private MKAnnotationView GetViewForAnnotation(MKMapView mapview, IMKAnnotation annotation)
    {
        return null;
    }
}

NMTAnnotationManager只是弱订阅INotifyCollectionChanged事件ObservableCollection在绑定中用作ItemsSource。当集合发生变化时,只需添加并删除MKMapView中的注释,此处不会发生任何神奇的事情。我已经确认它确实在IMKAnnotation中添加了不同的MKMapView实例(在这种情况下为13),并且可以在Annotations属性中检查它们。

正如@Philip在他的回答中所建议的,GetViewForAnnotation确实在将注释添加到MapView之前设置。但是如果我在方法中放置一个断点或一些痕迹,它就永远不会被击中。

上面的相同代码,只需要一个简单的MKMapViewDelegate,就像这样:

public class MyMapViewDelegate : MKMapViewDelegate
{
    public override void MapLoaded(MKMapView mapView)
    {
        Mvx.Trace("MapLoaded");
    }

    public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
    {
        Mvx.Trace("GetViewForAnnotation");
        return null;
    }
}

也不起作用。虽然每次渲染地图时都会遇到MapLoaded事件,但为什么GetViewForAnnotation没有被点击?

2 个答案:

答案 0 :(得分:2)

我这样做的方式是:

  • 带有ViewController的Storyboard,其中包含MKMapView
  • 在Connection Inspector的IB中设置了ViewController的MKMapView委托

ViewDidLoad我确保先设置它: mapView.GetViewForAnnotation += GetViewForAnnotation;

我遇到的问题从来没有被调用过,我修复了它,确保在添加一些注释之前我为GetViewForAnnotation设置了事件。

答案 1 :(得分:1)

好的,显然问题是PEBKAC。

注释确实已添加到Period#getDays()。但是,它们都没有设置MKMapView属性。很明显,地图不知道在哪里展示它们,也从未调用Coordinate