Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MKPinAnnotationView rightCalloutAccessoryView doesn't send calloutAccessoryControlTapped on iOS7

I'm trying to update one of my applications to iOS7. The problem is that, on my MKMapView, when I tap a pin, it shows the Callout, but when clicking on the rightCalloutAccessoryView, it doesn't send any callback to the delegate anymore. Thus I can't push the detail view anymore.

It worked fine on iOS6, doesn't anymore on iOS7.

Here is the relevent piece of code :

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }
    NSString * annotationIdentifier = nil;
    if ([annotation isKindOfClass:VPStation.class]) {
        annotationIdentifier = @"stationAnnotationIdentifier";
    }
    if (!annotation) {
        return nil;
    }
    MKPinAnnotationView * annotationView = [(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier] retain];
    if(annotationView == nil) {
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
        annotationView.canShowCallout = YES;
        annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        annotationView.image = [UIImage imageNamed:@"MyAnnotationPin"];
        annotationView.centerOffset = CGPointMake(-10.0f, 0.0f);
    }
    annotationView.annotation = annotation;

    return [annotationView autorelease];
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
    if ([view.annotation isKindOfClass:VPStation.class]) {
        VPTotalDetailViewController * detailVC = [[VPTotalDetailViewController alloc] initWithStation:(VPStation *)view.annotation
                                                                                      andUserLocation:self.mapView.userLocation.coordinate];
        [self.navigationController pushViewController:detailVC animated:YES];
        [detailVC release];
    }
}

According to MKAnnotationView class reference :

If the view you specify is also a descendant of the UIControl class, you can use the map view’s delegate to receive notifications when your control is tapped. If it does not descend from UIControl, your view is responsible for handling any touch events within its bounds.

Is there anything simpler than putting my own UIView subclass to get the touch and push the detailViewController ? Should I wait for Apple to fix this bug ? I believe it is a bug, isn't it?

Thanks in advance

like image 905
Nerkatel Avatar asked Dec 15 '22 06:12

Nerkatel


1 Answers

Alright, the problem here is that I have a UIGestureRecognizer set on the MKMapView (For what it's worth, it is a custom recognizer, but I don't believe this changes anything) and this gesture recognizer consumes the touch which is then not forwarded to the calloutAccessoryControl. Note that this behavior changed between iOS6 and iOS7. The fix was easy though, I added my controller as a delegate of the recognizer (it wasn't before) and implemented the UIGestureRecognizerDelegate method :

#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isKindOfClass:[UIControl class]]) {
        return NO;
    }
    return YES;
}
like image 173
Nerkatel Avatar answered Jan 04 '23 05:01

Nerkatel