Detect when a second annotation is selected in a MKMapView

不打扰是莪最后的温柔 提交于 2020-01-03 07:25:10

问题


When a use selects an annotation in a map, I show a bottom view with informations, such as the google maps app. I'm showing it in the map's delegate :

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view

When the user deselects it (by taping anywhere on the map), I hide my bottom view. This is done in the opposite delegate method :

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view

It works well, I'm happy with it. However, if a user selects a second annotation (ie: he taps a first annotation, then taps another one, without deselecting first the annotation in the meantime), I don't want to hide my bottom view then show it again. I'd just like to change informations in it.

However, as mapView:didDeselectAnnotationView: is called before mapView:didSelectAnnotationView:, I can't figure out how to detect the situation I'm describing above.

My question is : how can I detect that a user selects a second annotation OR, how should I solve this problem in any other way ?


回答1:


Maybe try put a delay in your didDeselectAnnotationView method to hide your bottomView. You need to store a reference to your last selected annotation view though.

Example:

@interface MyViewController
{
    MKAnnotationView *lastSelectedAnnotationView;
}

@end


@implementation MyViewController

...

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    ...

    [self updateBottomViewInfoWithAnnotationView:view];

    lastSelectedAnnotationView = view;
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    // ------------------------------------------------------------------
    // perform check to hide bottomView after a delay, to give
    // didSelectAnnotationView a chance to select new annotation
    // ------------------------------------------------------------------

    [self performSelector:@selector(checkShouldHideBottomView:) withObject:view afterDelay:0.5];
}

-(void)checkShouldHideBottomView:(MKAnnotationView *)lastDeselectedAnnotationView
{
    // ----------------------------------------------------------------------
    // Only hide bottom view if user did not select a new annotation or 
    // last selected annotation is the same as the one being deselected
    // ----------------------------------------------------------------------
    if(lastSelectedAnnotationView == nil || lastDeselectedAnnotationView == lastSelectedAnnotationView)
    {
        // hide your bottom view example
        self.bottomView.alpha = 0;

        // clear lastSelectedAnnotationView reference
        lastSelectedAnnotationView = nil;
    }
}



回答2:


This can be accomplished without adding an explicit delay by executing asynchronously on the main queue.

 var currentSelection: MKAnnotationView?
 func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
   currentSelection = view
   *** select code goes here ***
 }

 func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
   DispatchQueue.main.async { [weak self] in
     self?.delayedDeselect(view: view)
   }
 }

 func delayedDeselect(view: MKAnnotationView) {
   if currentSelection == view {
     *** deselect code goes here ***
   }
 }


来源:https://stackoverflow.com/questions/23667606/detect-when-a-second-annotation-is-selected-in-a-mkmapview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!