简体   繁体   中英

GetViewForAnnotation is never called

I am creating a MapView where I want to display some custom Annotations.

So I think usually what you do is add some IMKAnnotation to the MKMapView using the AddAnnotation method. I make sure to invoke that on the main thread like:

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

After these I are added I do see that the MKMapView now contains all the annotations I added in the Annotations property when inspecting with the debugger.

However, the problem is that GetViewForAnnotation is never invoked, no matter how I do it.

I've tried:

_mapView.GetViewForAnnotation += ViewForAnnotation;

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

I've tried implementing my own delegate:

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

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

I've tried using 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
    }
}

Nothing seems to trigger the GetViewForAnnotation method. Any ideas what I do wrong?

EDIT:

A bit more details what I have now.

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

The NMTAnnotationManager simply weak subscribes to the INotifyCollectionChanged event the ObservableCollection which is used as ItemsSource in the binding. When the collection changes it simply adds and removes the Annotations from the MKMapView , nothing magical happens here. I have verified that it does indeed add, in this case 13, different IMKAnnotation instances to the MKMapView and they can be inspected in the Annotations property of it.

So as @Philip suggested in his answer, GetViewForAnnotation does get set before Annotations are added to the MapView. But if I put a breakpoint or some trace in the method it never gets hit.

The same code above, just with a simple MKMapViewDelegate like so:

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

Does not work either. Although, the MapLoaded event gets hit for each time the map is rendered, but why does GetViewForAnnotation not get hit?

The way I'm doing it is:

  • Storyboard with a ViewController which contains a MKMapView
  • MKMapView Delegate to the ViewController is set in IB in the Connections Inspector

In ViewDidLoad I make sure I set this first: mapView.GetViewForAnnotation += GetViewForAnnotation;

I had problems with it never beeing called too, and I fixed it with making sure that I set the event for GetViewForAnnotation before I added some annotations.

OK, so apparently the problem was PEBKAC.

The annotation indeed got added to the MKMapView . However, none of them had their Coordinate property set. So obviously the map did not know where to present them and never called GetViewForAnnotation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM