Reputation: 5107
I am trying to show annotations on a mapView. All annotations come from JSON objects. They are divided into three groups. The user can select which annotations should be shown selecting an option on an segmentedIndex control.
As for now, the app is working as expected, the user selects an option from the segmentedIndex control, and the annotations are shown on the mapView.
My current issue is that I need the user to click on the callout view to open another viewController.
I think my code is right, but I guess it isn't then the showed callout view is the default calloutview, with title and subtitle. No action is fired when clicked on it.
Any help is welcome.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = @"MyLocation";
if ([annotation isKindOfClass:[PlaceMark class]]) {
MKPinAnnotationView *annotationView =
(MKPinAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
// Create a UIButton object to add on the
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[annotationView setRightCalloutAccessoryView:rightButton];
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[leftButton setTitle:annotation.title forState:UIControlStateNormal];
[annotationView setLeftCalloutAccessoryView:leftButton];
return annotationView;
}
return nil;
}
- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
if ([(UIButton*)control buttonType] == UIButtonTypeDetailDisclosure){
// Do your thing when the detailDisclosureButton is touched
UIViewController *mapDetailViewController = [[UIViewController alloc] init];
[[self navigationController] pushViewController:mapDetailViewController animated:YES];
} else if([(UIButton*)control buttonType] == UIButtonTypeInfoDark) {
// Do your thing when the infoDarkButton is touched
NSLog(@"infoDarkButton for longitude: %f and latitude: %f",
[(PlaceMark*)[view annotation] coordinate].longitude,
[(PlaceMark*)[view annotation] coordinate].latitude);
}
}
Upvotes: 1
Views: 652
Reputation:
Most likely the map view's delegate
is not set in which case it won't call viewForAnnotation
and will instead create a default view (red pin with a callout showing only the title and subtitle -- no buttons).
The declaration in the header file does not set the map view's delegate
. That just tells the compiler that this class intends to implement certain delegate methods.
In the xib/storyboard, right-click on the map view and connect the delegate
outlet to the view controller or, in viewDidLoad
, put mapView.delegate = self;
.
Unrelated, but I want to point out that in calloutAccessoryControlTapped
, rather than checking the buttonType, you probably want to just know whether it's the right or left button so just do:
if (control == view.rightCalloutAccessoryView) ...
See https://stackoverflow.com/a/9113611/467105 for a complete example.
There are at least two problems with checking the buttonType
:
UIButtonTypeDetailDisclosure
ends up actually creating a button of type Info (see MKAnnotationView always shows infoButton instead of detailDisclosure btn for details). So the check for buttonType UIButtonTypeDetailDisclosure would fail (on iOS 7).Upvotes: 1