I am having a problem with displaying a multiline MKAnnotaion in Xcode 4.2
here is my code that is displaying a single line subtitle for the annotation.
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString* MyAnnotationIdentifier = #"MyAnnotationIdentifier";
MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:MyAnnotationIdentifier] autorelease];
//--- adding pin color and animation
customPinView.pinColor = MKPinAnnotationColorRed;
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
So how to add a multiline subtitle?
Thanks in advance.
- (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;
}
also see this link for detail
How to display 2 lines of text for subtitle of MKAnnotation and change the image for the button on the right?
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;
}
Related
I m working on an app using MKMapView
there's some annotation and when u click on the annotation image , details are shown
for that i ve build my custom #interface Annotation : NSObject and added a boolean value "bClicked"
now I want the user to be able to click on a detail button inside the detailview but the code i ve made is not working :
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKAnnotationView *annotationView = nil;
int index = 0;
BOOL bFound = FALSE;
for (int i=0;i<[shopAnnotations count];i++)
{
if (annotation == [shopAnnotations objectAtIndex:i])
{
index = i;
bFound = TRUE;
break;
}
}
if (bFound==FALSE)
{
//ADLog(#"bFound FALSE annotation %p",annotation);
return annotationView; // <-- nil
}
Annotation *shopAnnotation = [shopAnnotations objectAtIndex:index];
annotationView = [_mapView dequeueReusableAnnotationViewWithIdentifier:shopAnnotation.identifier];
if (!annotationView)
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:shopAnnotation reuseIdentifier:shopAnnotation.identifier] autorelease];
for (UIView*view in annotationView.subviews)
{
[view removeFromSuperview];
}
annotationView.image = shopAnnotation.Image;
annotationView.alpha = 1.0f;
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.userInteractionEnabled = YES;
if (shopAnnotation.bClicked==TRUE)
{
UIView *detailView = [[UIView alloc ] initWithFrame:CGRectMake(0, -50, 290, 56)];
detailView.userInteractionEnabled = YES;
detailView.superview = annotationView;
[detailView release];
UIImageView *bg = [[UIImageView alloc ] initWithImage:[UIImage imageNamed:#"bulle_carte.png"]];
[bg setFrame:CGRectMake(0, 0, 290, 56)];
bg.superview = detailView;
[bg release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(250, 3, 35, 35)];
[button setImage:[UIImage imageNamed:#"fleche_bleue_d.png"] forState:UIControlStateNormal];
button.tag = [shopAnnotation.identifier intValue];
[button addTarget:self action:#selector(btnDetailPressed:) forControlEvents:UIControlEventTouchUpInside];
button.superview = detailView;
button.userInteractionEnabled = YES;
[annotationView setRightCalloutAccessoryView:detailView];
}
return annotationView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped");
}
-(void)btnDetailPressed:(id)sender
{
NSLog(#"btnDetailPressed");
}
when I click on the button or inside the DetailView, btnDetailPressed or calloutAccessoryControlTapped are not called/triggered.
Any suggestions?
Use the MKMapViewDelegate's method mapView:didSelectAnnotationView::
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[YOUR_CUSTOM_CLASS class]]) {
//customize it
}
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if ([view isKindOfClass:[YOUR_CUSTOM_CLASS class]]) {
//do something
}
}
Apple's doc
I want to add a UIImage in MKMapview.
i.e.: One a particular location, I want to add an image called "apple.jpg".
I don't know how to do that.
As I have already added a draggable pin as an annotation. But I don't know if I can add multiple images or not.
For add image as a Part of MKMapView see this Tutorial...
i.ndigo mkmapview
and for add Image as a Pin on MapView then use this bellow code...
MKAnnotationView *annotationView = [[[MKAnnotationView alloc] init];
annotationView.image = [UIImage imageNamed:#"apple.png"];
annotationView.annotation = annotation;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.rightCalloutAccessoryView.tag = 101;
annotationView.canShowCallout = YES;
[yourMapView addAnnotation:annotationView];
as #Kassem Bagher mentions, you need to create custom MKAnnotationView , check whatever tutorial (example)
Your image must be in png format see the code below.
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"] autorelease];
pinView.image = [UIImage imageNamed:#"apple.png"];
pinView.canShowCallout = YES;
}
}
This is working code and i already done with below code no necessory image is .png , .jpg or .gif its any formate you can use it
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
NSString *defaultPinID = #"myPin";
pinAnnotation = (MKPinAnnotationView *)[mapview dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.image = [UIImage imageNamed:#"marker_postoffice.png"];
pinAnnotation.annotation = annotation;
pinAnnotation.canShowCallout = YES;
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton addTarget:self action:#selector(showDetails)forControlEvents:UIControlEventTouchUpInside];
pinAnnotation.rightCalloutAccessoryView = infoButton;
// now you can set diff image by [annotation title] you can set diff image with if else condition like below code
if([[annotation title] isEqualToString:objAppDelegate.OfficePinTitle])
{
pinAnnotation.image = [UIImage imageNamed:#"marker_postoffice.png"];
pinAnnotation.annotation = annotation;
pinAnnotation.canShowCallout = YES;
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
infoButton addTarget:self
action:#selector(showDetails)forControlEvents:UIControlEventTouchUpInside];
pinAnnotation.rightCalloutAccessoryView = infoButton;
}
else
{
pinAnnotation.image = [UIImage imageNamed:#"marker_red_postoffice.png"];
pinAnnotation.canShowCallout = YES;
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton addTarget:self action:#selector(showDetails)forControlEvents:UIControlEventTouchUpInside];
pinAnnotation.rightCalloutAccessoryView = infoButton;
}
}
I am getting weird stuff in custom MKAnnotaionView. When I click on pin it does not show its detail. Am I making any mistake?
Here is my code:
- (MKAnnotationView *) mapView:(MKMapView *)mapView1 viewForAnnotation:(id
<MKAnnotation>) annotation
{
MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:#"redpin"];
annotationView.pinColor = MKPinAnnotationColorRed;
annotationView.animatesDrop = YES;
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button.frame = CGRectMake(0, 0, 23, 23);
annotationView.rightCalloutAccessoryView = button;
// Image and two labels
UIView *leftCAV = [[UIView alloc] initWithFrame:CGRectMake(0,0,23,23)];
UILabel *label1 = [[UILabel alloc]init];
label1.text = [NSString stringWithFormat:#"hello"];
[leftCAV addSubview :label1];
annotationView.leftCalloutAccessoryView = leftCAV;
annotationView.canShowCallout = YES;
return annotationView;
}
I am developing a custom pins in a MapView in my iPhone app.
Here is the code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
if ([[annotation title] isEqualToString:NSLocalizedString(#"Current Location",#"")]) {
MKPinAnnotationView *pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
//pin.pinColor = MKPinAnnotationColorRed;
annotationView = pin;
}
else
{
NSString *pin = [NSString stringWithFormat:#"pin%i.png",[[annotation imgNumber] intValue]];
annotationView.image = [UIImage imageNamed:pin];//Canviar la chincheta per numero
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[annotationView setRightCalloutAccessoryView:button];
annotationView.annotation = annotation;
annotationView.canShowCallout = YES;
/********* Imagen a la izquierda en la burbuja *********/
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
// Set up the Left callout
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeCustom];
myDetailButton.frame = CGRectMake(0, 0, 23, 23);
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
// Set the image for the button
//[myDetailButton setImage:[UIImage imageNamed:#"botocorreu.png"] forState:UIControlStateNormal];
NSString *detailButton = [NSString stringWithFormat:#"%i",[[annotation imgNumber] intValue]];
[myDetailButton setImage:[UIImage imageNamed:detailButton] forState:UIControlStateNormal];
// Set the button as the callout view
annotationView.leftCalloutAccessoryView = myDetailButton;
annotationView.canShowCallout = YES;
}
return annotationView;
}
This works good but show me the users location with a red pin.
I check the "show user location" in the IB.
i would like to use the default blue point which will move it automatically when the user is moving, isn't correct?
How can i do that?
Thanks a lot.
Add this to the top of the viewForAnnotation method:
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
The special user location annotation is of type MKUserLocation and returning nil in that case tells the map view to draw the default view for it which is the blue dot.
You can also remove these lines since they will no longer be needed:
if ([[annotation title] isEqualToString:NSLocalizedString(#"Current Location",#"")]) {
MKPinAnnotationView *pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
//pin.pinColor = MKPinAnnotationColorRed;
annotationView = pin;
}
else
I am annotating my map and setting an image just fine, but when I tap the annotation on the MapView, the image goes from my custom image back to the red pin. Why is this?
- (MKAnnotationView *)mapView:(MKMapView *)newMapView viewForAnnotation:(id )newAnnotation {
MKPinAnnotationView *annotation = [[MKPinAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:#"currentloc"];
if (annotation == nil) {
annotation = [[MKAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:#"currentloc"];
}
annotation.image = [UIImage imageNamed:#"anno.png"];
annotation.canShowCallout = YES;
annotation.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bus_stop_30x30.png"]];
annotation.leftCalloutAccessoryView = imgView;
return annotation;
}
My code looks identical to some sample code that does not produce this problem.
Answering my own question here, just in case others have the same issue. Notice that I am using "MKPinAnnotationView" - it should be changed to "MKAnnotationView" and everything works.
Fixed code:
- (MKAnnotationView *)mapView:(MKMapView *)newMapView viewForAnnotation:(id )newAnnotation {
MKAnnotationView *annotation = [[MKAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:#"currentloc"];
if (annotation == nil) {
annotation = [[MKAnnotationView alloc] initWithAnnotation:newAnnotation reuseIdentifier:#"currentloc"];
}
annotation.image = [UIImage imageNamed:#"anno.png"];
annotation.canShowCallout = YES;
annotation.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bus_stop_30x30.png"]];
annotation.leftCalloutAccessoryView = imgView;
return annotation;
}
I think this is one of the best ways:
(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
NSLog(#"welcome into the map view annotation");
MyAnnotation* myAnnotation1=annotation;
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if([mapView isEqual:mapMainView]== NO)
{
return nil;
}
// try to dequeue an existing pin view first
// if ([annotation isKindOfClass:[myAnnotation1 class]])
// {
// try to dequeue an existing pin view first
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (nil == pinView)
{
MKAnnotationView* annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier] autorelease];
// annotationView.canShowCallout = YES;
// pinView.animatesDrop=YES;
//pinView.pinColor=MKPinAnnotationColorPurple;
//image
UIImage* flagImage = [UIImage imageNamed:#"map_marker_over2.png"];
CGRect resizeRect;
resizeRect.size = flagImage.size;
CGSize maxSize = CGRectInset(self.view.bounds,
[MapPropertyViewController annotationPadding],
[MapPropertyViewController annotationPadding]).size;
maxSize.height -= self.navigationController.navigationBar.frame.size.height + [MapPropertyViewController calloutHeight];
if (resizeRect.size.width > maxSize.width)
resizeRect.size = CGSizeMake(maxSize.width, resizeRect.size.height / resizeRect.size.width * maxSize.width);
if (resizeRect.size.height > maxSize.height)
resizeRect.size = CGSizeMake(resizeRect.size.width / resizeRect.size.height * maxSize.height, maxSize.height);
resizeRect.origin = (CGPoint){0.0f, 0.0f};
UIGraphicsBeginImageContext(resizeRect.size);
[flagImage drawInRect:resizeRect];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
annotationView.image = resizedImage;
annotationView.opaque = NO;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
rightButton.tag = myAnnotation1.tagAnnotation;
annotationView.rightCalloutAccessoryView = rightButton;
profileIconView = [[UIImageView alloc]initWithFrame:CGRectMake(18.5f, 10.0f, 37.0f, 30.0f)];
annotationView.leftCalloutAccessoryView = profileIconView;
//image
img = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:[arrImages objectAtIndex:myAnnotation1.tagAnnotation]]]];
NSLog(#"Annotation Click %d",[arrImages count]);
NSLog(#"image %#",img);
profileIconView.image=img;
[profileIconView release];
[annotationView setEnabled:YES];
[annotationView setCanShowCallout:YES];
return annotationView;
}
return pinView;
// }
// return nil;
}
Try this if you want to set both Source to Destination pin images different.
MKPointAnnotation * sourceAnno= [[MKPointAnnotation alloc] init];
sourceAnno.coordinate=CLLocationCoordinate2DMake(YourSourcelatitude,YourSourcelongitude);
[sourceAnno setAccessibilityLabel:#“Source”];
sourceAnno.title = #“You”;
[mapview addAnnotation: sourceAnno];
DestinationAnno = [[MKPointAnnotation alloc] init];
DestinationAnno.coordinate = CLLocationCoordinate2DMake(YourDestinationlatitude,YourDestinationlongitude);
[DestinationAnno setAccessibilityLabel:#“Destination”];
DestinationAnno.title =#“Destination”;
[mapview addAnnotation: DestinationAnno];
In Delegate Method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPointAnnotation *PointAnno=(MKPointAnnotation *)annotation;
NSString * kPinAnnotationIdentifier = PointAnno.accessibilityLabel;
MKAnnotationView *AnnotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:kPinAnnotationIdentifier];
if ([kPinAnnotationIdentifier isEqualToString:#"Source"])
{
AnnotationView.centerOffset = CGPointMake(8, -14);
AnnotationView.calloutOffset = CGPointMake(-8, 0);
AnnotationView.image = [UIImage imageNamed:#"pin_blue.png"];
AnnotationView.canShowCallout = YES;
}
else if([kPinAnnotationIdentifier isEqualToString:#"Destination"])
{
AnnotationView.centerOffset = CGPointMake(8, -14);
AnnotationView.calloutOffset = CGPointMake(-8, 0);
AnnotationView.image = [UIImage imageNamed:#"pin_red.png"];
AnnotationView.canShowCallout = YES;
}
return AnnotationView;
}
Thank you