Alan Moore
Alan Moore

Reputation: 6575

How do I put a right accessory button onto the current location callout?

I want to add a right accessory button to the current user location callout. I've found a few questions on the topic but they don't seem to work for me. Here is the code I have so far, I have successfully put the right accessory button onto my other annotations:

- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
        //TODO: this doesn't seem to be working?  
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        MKAnnotationView * aV = [mapView viewForAnnotation:annotation];
        aV.canShowCallout = YES;
        aV.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        return nil;
    }
    return nil;
}

I've read in a few places that the solution is to make a custom MKAnnotationView for the User Location but I haven't seen a demonstration of how this is done for the user location -- I have successfully done this for the other annotations on my map.

Sample code would be the most helpful, thanks!

Upvotes: 2

Views: 5924

Answers (2)

chatur
chatur

Reputation: 2363

Again you should get reference of user location annotation view. Following methods gets called in iOS >= 5

Option 1

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    MKAnnotationView *aV; 
     for (aV in views) {
           if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
                MKAnnotationView* annotationView = aV;
                annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            }
     }
}

See the delegate method below as well

Alternative Method

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
     MKAnnotationView* annotationView = [mapView viewForAnnotation:userLocation];   
     annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}

Make sure to add the delegate method so you can do whatever when the callout button is tapped:

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

In any iOS either of these method gets called and you can add right/left accessorybutton to it. ensure that you do not add this button twice by checking subview count of user location annotation view.

You can also add/remove accessoryviews it in runtime, but I believe you will not want to remove it.buttons

Upvotes: 9

brendan
brendan

Reputation: 1735

Your main problem is that you are returning nil in both cases. You should also use a reuse identifier.

- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
 {

 if ([annotation isKindOfClass:[MKUserLocation class]]) {
    MKAnnotationView * aV = [mapView dequeueReusableAnnotationViewWithIdentifier:@"locationView"];
    if (aV == nil) 
       aV = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"locationView"];
    aV.canShowCallout = YES;
    aV.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    return aV;
  }
return nil;
}

You will also need to implement:

- (void)mapView:(MKMapView *)_mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

for the behavior of the callout accessory.

Upvotes: 1

Related Questions