MvvmCross iOS: How to bind MapView Annotation to j

2019-05-23 09:32发布

How can I bind the MapView's annotation to switch to different view when it's callout accessory button is clicked? How do I implement the annotation's CalloutAccessoryControlTapped method?

Or what is the best way to do it?

Here is my code:

[Register("MapView")]
public class MapView : MvxViewController
{

    public override void ViewDidLoad()
    {
        Title = "Map";
        base.ViewDidLoad();

        var mapView = new MKMapView(new RectangleF(0, 0, 320, UIScreen.MainScreen.Bounds.Height - 20 - 44))
            {
                MapType = MKMapType.Standard,
                ZoomEnabled = true,
                ScrollEnabled = true,
                Delegate = new MapDelegate(),
            };
        View.AddSubview(mapView);

        var center = new CLLocationCoordinate2D(ViewModel.CurrentLat, ViewModel.CurrentLong);
        var span = new MKCoordinateSpan(5.0, 5.0);
        var region = new MKCoordinateRegion(center, span);
        mapView.SetRegion(region, true);

        mapView.AddAnnotation(CreateNewAnnotation(ViewModel.CurrentLat, ViewModel.CurrentLong, "You are here"));

        var set = this.CreateBindingSet<MapView, MapViewModel>();
        set.Bind(mapView).For(???).To(vm => vm.showDetailCommand); // how can I bind to the map annotation and switch to other view when user click it?
        set.Apply();
    }

    protected class MapDelegate : MKMapViewDelegate
    {
        public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, MonoTouch.Foundation.NSObject annotation)
        {
            var pinId = "locationPinId";
            var pinView = (LocationAnnotationView)mapView.DequeueReusableAnnotation(pinId) ??
                          new LocationAnnotationView
                    {
                        Annotation = annotation,
                        RestorationIdentifier = pinId,
                        Image = UIImage.FromBundle("images/map_pointer_icon_small.png"),
                    };

                var buttonView = new UIButton(new RectangleF(0, 0, 27, 27));
                buttonView.SetImage(UIImage.FromBundle("images/blue_arrow.png"), UIControlState.Normal);
                buttonView.Tag = 88888;
                pinView.RightCalloutAccessoryView = buttonView;

            return pinView;
        }

        public override void CalloutAccessoryControlTapped(MKMapView mapView, MKAnnotationView view, UIControl control)
        {
            // how can I bind this method, so when the user click on the annotation it can switch to other view?
        }
    }
}

1条回答
Emotional °昔
2楼-- · 2019-05-23 09:58

You could do this in lots of ways.

Given that you are already using fixed non-binding (non-updating) single item display, then the easiest approach is probably for you to just extend your Annotation so that it is created with an ICommand as well as the lat, lng and label:

CreateNewAnnotation(
  ViewModel.CurrentLat, 
  ViewModel.CurrentLong, 
  ViewModel.ShowDetailCommand, 
  "You are here")

Once this is done, then the ICommand:

  • can then easily be invoked from your call-out or from your buttonView's TouchUpInside or from your CalloutAccessoryControlTapped handler.
  • can be implemented inside ShowDetailCommand as a navigation command - see N=5 in http://mvvmcross.wordpress.com/ for examples of navigations.

If you do want a much more dynamic annotation - with true data-binding, then you would need to start looking at adding data-binding to your custom Annotation class, to your custom AnnotationView and perhaps also to your custom MapViewDelegate - this would be similar to the way data-binding is added to a UIView - see MvxView.cs - but is probably overkill for your current example.

查看更多
登录 后发表回答