MKUserLocation is selectable, falsely intercepting touches from custom MKAnnotationViews
Asked Answered
I

2

7

I have a normal map in my iOS app where "Shows Users Location" is enabled - meaning I have my normal blue dot on the map, showing my position and accuracy info. The callout is disabled in code.

But I also have custom MKAnnotationViews that are plotted around the map which all have custom callouts.

This is working fine, but the problem is that when my location is on the location of a MKAnnotationView, the blue dot (MKUserLocation) intercepts the touch, so the MKAnnotationView doesn't get touched.

How can I disable the user interaction on the blue dot so that the touches are intercepted by the MKAnnotationViews and not the blue dot?

This is what I do so far:

- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation;
{
    if (annotation == self.mapView.userLocation)
    {
        [self.mapView viewForAnnotation:annotation].canShowCallout = NO;
        return [self.mapView viewForAnnotation:annotation];
    } else {
        ...
    }
}
Informed answered 26/2, 2014 at 9:42 Comment(0)
F
17

Disabling the callout doesn't disable touches on the view (didSelectAnnotationView will still get called).

To disable user interaction on an annotation view, set its enabled property to NO.

However, instead of setting enabled to NO in the viewForAnnotation delegate method, I suggest doing it in the didAddAnnotationViews delegate method instead and in viewForAnnotation, just return nil for MKUserLocation.

Example:

- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation;
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        return nil;
    }

    //create annotation view for your annotation here...
}

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    MKAnnotationView *av = [mapView viewForAnnotation:mapView.userLocation];
    av.enabled = NO;  //disable touch on user location
}
Farlay answered 26/2, 2014 at 13:29 Comment(2)
I'm suggesting setting enabled to NO in didAddAnnotationViews for the user location annotation only. If you wanted to disable interaction on your own annotations, you can do that in viewForAnnotation when creating your view.Farlay
Excellent suggestion using enabled instead of userInteractionEnabled. Solved my problem with stacked annotations!Lave
G
0

Swift 4.2 Example:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation)   ->     MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }
// Add custom annotation views here.
}

func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView])      {
    // Grab the user location annotation from your IB Outlet map view.
    let userLocation = mapView.view(for: mapView.userLocation)
    userLocation?.isEnabled = false
}
Grassy answered 19/9, 2018 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.