How to display 2 lines of text for subtitle of MKAnnotation and change the image for the button on the right?
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
// Button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 23, 23);
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[button setImage:[UIImage imageNamed:yourImageName] forState:UIControlStateNormal];
[advertButton addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];
annView.rightCalloutAccessoryView = button;
// Image and two labels
UIView *leftCAV = [[UIView alloc] initWithFrame:CGRectMake(0,0,23,23)];
[leftCAV addSubview : yourImageView];
[leftCAV addSubview : yourFirstLabel];
[leftCAV addSubview : yourSecondLabel];
annotationView.leftCalloutAccessoryView = leftCAV;
annotationView.canShowCallout = YES;
return pin;
}
UPDATE
The default style for annotations only supports the title and subtitle. Neither title nor subtitle can include line breaks. You cannot do this without subclassing.
To use a custom view review Apple's sample code:
http://developer.apple.com/library/ios/#samplecode/WeatherMap/Introduction/Intro.html
I also think there is a problem in your code
UILabel *l1=[[UILabel alloc] init];
l1.frame=CGRectMake(0, 15, 50, 50);
l1.text=@"First line of subtitle";
l1.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
UILabel *l2=[[UILabel alloc] init];
l2.frame=CGRectMake(0, 30, 50, 50);
l2.text=@"Second line of subtitle";
l2.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
[leftCAV addSubview : l1];
[leftCAV addSubview : l2];
l1 has a frame (0, 15, 50, 50) and l2 has (0, 30, 50, 50). Wont these two overlap? I mean l1 will start from y=15 and its height is 50. so when l2 starts from 30 it may overlap.. Can you pls check by changing the frames
plz use this
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = (CustomAnnotation *) annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotation"];
if (annotationView == nil)
annotationView = customAnnotation.annotationView;
else
annotationView.annotation = annotation;
//Adding multiline subtitle code
UILabel *subTitlelbl = [[UILabel alloc]init];
subTitlelbl.text = @"sri ganganagar this is my home twon.sri ganganagar this is my home twon.sri ganganagar this is my home twon. ";
annotationView.detailCalloutAccessoryView = subTitlelbl;
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:150];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:subTitlelbl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0];
[subTitlelbl setNumberOfLines:0];
[subTitlelbl addConstraint:width];
[subTitlelbl addConstraint:height];
return annotationView;
} else
return nil;
}
This is how I achieved it without subclassing the annotation view, or using undocumented APIs:
MKAnnotationView* pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomPinAnnotationView"];
// Add a custom view to the the callout to allow mutli-line text
UIView *calloutView = [[UIView alloc] initWithFrame:CGRectMake(0, 10, 250, 250)];
UIView *calloutViewHeight = [[UIView alloc] initWithFrame:CGRectMake(0, 10, 1, 250)]; // The reason for this will become apparent below
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 250, 21)];
[title setText:<<your single-line title text>>];
[calloutView addSubview:title];
UILabel *subtitle = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, 250, 250)];
[subtitle setNumberOfLines:0];
[subtitle setText:<<your multi-line title text>>];
CGSize subtitleSize = [subtitle sizeThatFits:CGSizeMake(250, 250)];
[subtitle setFrame:CGRectMake(10, 35, 250, subtitleSize.height)];
[calloutView addSubview:subtitle];
[calloutView setFrame:CGRectMake(0, 10, 250, 35+subtitleSize.height+10)];
[calloutViewHeight setFrame:CGRectMake(0, 0, 1, 35+subtitleSize.height+10)];
pinView.leftCalloutAccessoryView = calloutView;
pinView.rightCalloutAccessoryView = calloutViewHeight; // The height of the callout is calculated by the right accessory *not* the left, so this fake view is required
You can customize the font/color of the text by adjusting title
and subtitle
accordingly.
Sure it's a bit of a hack, but it achieves the desired results without subclassing, and allows you to customize with whatever additional buttons/images you'd like to add calloutView
(and you can still place buttons in the right-accessory view if you wish, as long as you retain the height).