4

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

2 Answers2

2

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;
    }
}
Tammo Freese
  • 10,514
  • 2
  • 35
  • 44
0

I don't know the correct solution to this problem, but I have a hacky one for you. You need to trigger relayout of the view and it could be achieved by messing with the accessory view. You're not using left accessory view here, so you can set it to something and the set it back to nil. Like this:

self.pin.title = @"Ozone Level: 100";
self.pin_view.leftCalloutAccessoryView = [[[UIView alloc] init] autorelease];
self.pin_view.leftCalloutAccessoryView = nil;

I tried and it works on iOS 5. Cannot test on iOS 6.

If you do that often then it's good not to create UIView all the time, but rather reuse something.

I had the same problem, when I was updating rightCalloutAccessoryView. It only worked if I first set it to nil and then right away set it to whatever I needed in the first place.

detunized
  • 15,059
  • 3
  • 48
  • 64
  • @user1724168, are you updating `title` somewhere else later? The code you posted shows the place where you create the annotation. You problem comes later, when you update the text. You need to move my hack to that place. Here you don't need it. – detunized Nov 08 '12 at 00:59
  • please see latest code above at the button, two lines of code! –  Nov 08 '12 at 01:10
  • @user1724168, yeah, right after it try sticking my two lines. It should help. – detunized Nov 08 '12 at 01:25
  • it still gives me same bug. annotation.title=[NSString stringWithFormat:@"Ozone Level:%@",[attr2 stringValue]]; pinView.leftCalloutAccessoryView = [[UIView alloc] init]; pinView.leftCalloutAccessoryView = nil; –  Nov 08 '12 at 03:57
  • Then this hack no longer applies to iOS 6. Sorry. – detunized Nov 08 '12 at 12:19