Creating custom pins for iPhone Mapkit - iphone

I am trying something a little different.
Instead of a class, I have used MKPinAnnotationView and the inherited image instance. Here is the code for viewForAnnotation. But it doesn't work. Nothing shows at all.
I also tried it using MKAnnotationView and I get the same result.
- (MKAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation {
int postTag = 0;
MKAnnotationView *pinView = (MKAnnotationView*)[eMapView dequeueReusableAnnotationViewWithIdentifier:#"Pin"];
if(pinView == nil) {
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"Pin"];
pinView.frame = CGRectMake(0, 0, 25, 25);
} else {
pinView.annotation = annotation;
}
pinView.image = [UIImage alloc];
NSString *data_annotation = [annotation getData];
if([data_annotation length] == 0) {
pinView.image = [UIImage imageNamed:#"pinYellow.png"];
// pinView.pinColor = MKPinAnnotationColorGreen;
}
else if(([[data_annotation rangeOfString:#"GRAY"].location != NSNotFound)){
pinView.image = [UIImage imageNamed:#"pinGray.png"];
// pinView.pinColor = MKPinAnnotationColorPurple;
}
else {
pinView.image = [UIImage imageNamed:#"pinRed.png"];
// pinView.pinColor = MKPinAnnotationColorRed;
}
// Set up the Right callout
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
myDetailButton.frame = CGRectMake(0, 0, 23, 23);
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[myDetailButton addTarget:self action:#selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
// Identify which pin is being selected
if ([[annotation title] isEqualToString:#"Current Location"]) {
postTag = 99999;
} else {
postTag = [annotation getPinID];
}
myDetailButton.tag = postTag;
pinView.rightCalloutAccessoryView = myDetailButton;
//pinView.animatesDrop = YES;
// Set to show a callout on the pin
pinView.canShowCallout = YES;
return pinView;
}

Related

Setting image for MKAnnotation

I added MKAnnotation in my mapview using the following code.
Flag *flag = [[Flag alloc] init];
flag.title = #"Golf Course";
flag.subtitle = #"Green";
flag.coordinate =CLLocationCoordinate2DMake(28.457394,77.108667);
[mapView addAnnotation:flag];
and am setting image like
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation
{
if(([annotation isKindOfClass:[Flag class]]))
{
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"PinId1";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:#"pin1"] autorelease];
//pinView= [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin1"];
pinView.canShowCallout = YES;
pinView.draggable = YES;
[pinView setImage:[UIImage imageNamed:#"flag2.png"]];
}
else
{
[mapView.userLocation setTitle:#"I am here"];
}
}
return pinView;
}
but am not getting the image for MKAnnoation.What is wrong am doing?Please help me.
I have the same issue. Now using the working version as given below.
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if ([annotation isKindOfClass:[Annotation class]])
{
static NSString* SFAnnotationIdentifier = #"SFAnnotationIdentifier";
MKPinAnnotationView* pinView =
(MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:SFAnnotationIdentifier];
if (!pinView)
{
MKAnnotationView *annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:SFAnnotationIdentifier] autorelease];
annotationView.canShowCallout = YES;
UIImage *flagImage = [UIImage imageNamed:#"map_pin.png"];
CGRect resizeRect;
resizeRect.size = flagImage.size;
CGSize maxSize = CGRectInset(self.view.bounds,
10.5,
10.5).size;
maxSize.height -= self.navigationController.navigationBar.frame.size.height + 40.0;
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];
Annotation *annoterObject = (Annotation *) annotation;
rightButton.tag = annoterObject.annoteCount;
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = rightButton;
return annotationView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
This is the working code.
Where you have to set image?is it on callouts? if yes replace [pinView setImage:[UIImage imageNamed:#"flag2.png"]]; with pinView.leftCalloutAccessoryView = [[ UIImageView alloc]initWithImage:[UIImage imageNamed:#"flag2.png"]];

adding button to annotation bubble in mapview

The following is my code for adding annotation into a mapview. This code is called in viewdidload method
-(void)displayMYMap
{
MKCoordinateRegion region = mapView.region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
addAnnotation = [[[AddressAnnotation alloc] initWithCoordinate:mapCenter title:firstName SubTitle:lastName Recordid:passedRecordID]autorelease];
[mapView addAnnotation:addAnnotation];
region.span=span;
region.center=mapCenter;
}
I am trying to add a button to my annotation bubble. I am getting an exception while I am trying to add the button to the annotationview.
UIButton *informationButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure ];
addAnnotation.rightCalloutAccessoryView = informationButton;
This is the code I have written to add the button. I cant figure out a reason for the exception.
use delegate method of Annotation,
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *identifier = #"RoutePinAnnotation";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
if ([(UICCircleAnnotation *)annotation annotationType] == UICCircleAnnotationTypeOther) {
pinView.pinColor = MKPinAnnotationColorPurple;
} else if ([(UICCircleAnnotation *)annotation annotationType] == UICCircleAnnotationTypeContact) {
pinView.pinColor = MKPinAnnotationColorRed;
}
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(buttonMethod:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile.png"]];
pinView.leftCalloutAccessoryView = profileIconView;
[profileIconView release];
return pinView;
}
in delegate method of Annotation View,
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *identifier = #"RoutePinAnnotation";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
if ([(UICCircleAnnotation *)annotation annotationType] == UICCircleAnnotationTypeOther) {
pinView.pinColor = MKPinAnnotationColorPurple;
} else if ([(UICCircleAnnotation *)annotation annotationType] == UICCircleAnnotationTypeContact) {
pinView.pinColor = MKPinAnnotationColorRed;
}
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return pinView;
}
You will get disclosure button on the annotation bubble.

show users location blue point in iPhone MKMapView

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

iphone pinView.animatesdrop not working

Here is my code of - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation method. The method is getting called but the pinView.animatesDrop = YES and pinView.canShowCallout = YES is not working. Please help
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#","];
NSLog(#"pin map");
if(pinView == nil)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#""];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIImage *image = [UIImage imageNamed:#"ann.png"];
CGRect resizeRect;
resizeRect.size = image.size;
CGSize maxSize = CGRectInset(self.view.bounds,
[map annotationPadding],
[map annotationPadding]).size;*/
maxSize.height -= self.navigationController.navigationBar.frame.size.height + [map 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);
[image drawInRect:resizeRect];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
pinView.image = resizedImage;
pinView.opaque = NO;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == mapView.userLocation)
{
return nil;
}
return pinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
please see this blog-
here
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
{
NSLog(#"welcome into the map view annotation");
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// try to dequeue an existing pin view first
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.pinColor=MKPinAnnotationColorPurple;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile.png"]];
pinView.leftCalloutAccessoryView = profileIconView;
[profileIconView release];
return pinView;
}
I worked out what my problem was:
I had not set the delegate for the class.mapView.delegate=self;

Why does a custom MKMapView annotation image disappear on touch?

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