Search code examples
iosios6mkmapviewios6-maps

Map Annotation showCallout-iOS


I have problem to show the annotation title as shown in the following images. First image denotes value very well; on the other hand, once value goes up to three digits then title shows three dots as shown in the second image. I would like to know how to fix this problem. Any idea would be more than welcome!. Thanks a lot in advance, appreciated! I have just put my code here for reference!

- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation {
   MKAnnotationView *pinView=nil;
    if(![annotation isKindOfClass:[Annotation class]]) // Don't mess user location
        return nil;

    static NSString *defaultPinID = @"StandardIdentifier";
    pinView = (MKAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
    if (pinView == nil){
        pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
    }

    if ([annotation isKindOfClass:[Annotation class]]) {
        Annotation *a = (Annotation *)annotation;

        pinView.image = [ZSPinAnnotation pinAnnotationWithColor:a.color];
        pinView.annotation = a;
        pinView.enabled = YES;
        pinView.centerOffset=CGPointMake(6.5,-16);
        pinView.calloutOffset = CGPointMake(-11,0);

    }

    pinView.canShowCallout = YES;
    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [rightButton setTitle:annotation.title forState:UIControlStateNormal];
    [pinView setRightCalloutAccessoryView:rightButton];
    pinView.leftCalloutAccessoryView = [[UIView alloc] init];
    pinView.leftCalloutAccessoryView=nil;

    return pinView;
  }

My showCallout title is updated in the following code:

NSNumber *attr2=[attr valueForKey:@"ozone_level"];
annotation.title=[NSString stringWithFormat:@"Ozone Level:%@",[attr2 stringValue]];

enter image description here enter image description here


Solution

  • The problem is that the callout view's layout is not recalculated when the title changes. Maybe you should file a bug report for that.

    To force a relayout, you can deselect and select the annotation programmatically if the callout is visible. It's not animated, but it changes the width of the callout:

    NSNumber *attr2=[attr valueForKey:@"ozone_level"];
    annotation.title=[NSString stringWithFormat:@"Ozone Level:%@",[attr2 stringValue]];
    
    
    if ([self.mapView viewForAnnotation:annotation] != nil) {
        NSArray *selectedAnnotations = self.mapView.selectedAnnotations;
        if ((selectedAnnotations != nil) && ([self.mapView.selectedAnnotations indexOfObject:annotation] != NSNotFound)) {
            [self.mapView deselectAnnotation:annotation animated:NO];
            [self.mapView selectAnnotation:annotation animated:NO];
        }
    }
    

    You should also delete this line, as the title of the annotation is used as text label on the annotation anyway:

    [rightButton setTitle:annotation.title forState:UIControlStateNormal];
    

    UPDATE:

    The solution @detunized provided works with animation. Instead of creating an unneeded UIView though, you can better remove and re-add the button view:

    NSNumber *attr2=[attr valueForKey:@"ozone_level"];
    annotation.title=[NSString stringWithFormat:@"Ozone Level:%@",[attr2 stringValue]];
    
    MKAnnotationView *annotationView = [self.mapView viewForAnnotation:annotation];
    // The annotation must be visible, otherwise a refresh isn't needed
    if (annotationView != nil) {
        NSArray *selectedAnnotations = self.mapView.selectedAnnotations;
        // The annotation must be selected, otherwise a refresh isn't needed
        if ((selectedAnnotations != nil) && ([self.mapView.selectedAnnotations indexOfObject:annotation] != NSNotFound)) {
                // Unset and re-set the right button to force relayout
                UIView *view = annotationView.rightCalloutAccessoryView;
                annotationView.rightCalloutAccessoryView = nil;
                annotationView.rightCalloutAccessoryView = view;
        }
    }