I have dot as a pin annotation in map and showing custom annotation view.My problem is that when I click on dot sometimes dot behinds custom annotation view comes in fron of custom annotation view instead of showing behind it.
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKAnnotationView *annotationView;
PinAnnotationView *pinView = nil;
NSString *identifier;
if ([annotation isKindOfClass:[DisplayMap class]])
{
identifier = #"Pin";
NSInteger myid = ((DisplayMap *)annotation).takeid;
MKAnnotationView *pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
DisplayMap *a = (DisplayMap *)annotation;
pinView.annotation=a;
if (myid == 1)
{
UIImage *test = [UIImage imageNamed:#"red_dot.png"];
pinView.image = test;
pinView.opaque = NO;
}
else if (myid == 2)
{
UIImage *test = [UIImage imageNamed:#"blue_dot.png"];
pinView.image = test;
pinView.opaque = NO;
}
else {
UIImage *test = [UIImage imageNamed:#"green_dot.png"];
pinView.image = test;
pinView.opaque = NO;
}
return pinView;
}
else if ([annotation isKindOfClass:[CalloutAnnotation class]])
{
identifier = [NSString stringWithFormat:#"Callout%d",pinView.tag];
annotationView = [[CalloutAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
CalloutAnnotation *calloutAnnotation = (CalloutAnnotation *)annotation;
((CalloutAnnotationView *)annotationView).title = calloutAnnotation.title;
((CalloutAnnotationView *)annotationView).iTag = calloutAnnotation.iTag;
[annotationView setNeedsDisplay];
[UIView animateWithDuration:0.5f
animations:^(void) {
mapView.centerCoordinate = calloutAnnotation.coordinate;
}];
annotationView.annotation = annotation;
return annotationView;
}
}
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view1
{
if ([view1.annotation isKindOfClass:[DisplayMap class]])
{
DisplayMap *pinAnnotation = ((DisplayMap *)view1.annotation);
LoginDetail *obj = [[appDelegate mapArray] objectAtIndex:pinAnnotation.iTag];
[mapView removeAnnotations:annotationRemoveArray];
CalloutAnnotation *calloutAnnotation = [[CalloutAnnotation alloc] init];
calloutAnnotation.title = pinAnnotation.title;
pinAnnotation.calloutAnnotation = calloutAnnotation;
[mapView addAnnotation:calloutAnnotation];
[annotationRemoveArray addObject:calloutAnnotation];
[self setzoomonselectannotation:pinAnnotation.coordinate];
}
}
The callout window is an annotation view as well. That is wrong ;)
follow one the hints:
How to customize the callout bubble for MKAnnotationView?
Basically what they say: make the callout a subview of the pin itself
Related
I have made these pieces of code for my custom annotation:
- (void)viewDidLoad
{
[super viewDidLoad];
mapView.delegate=self;
[self AddLocations];
[self initiateMap];
......
this is my addLocation function:
-(id<MKAnnotation>)addAnnotationWithTitle: (NSString*) title coordinate:(CLLocationCoordinate2D)
Location imageName:(NSString*) imageName{
CustomAnnotation *annotation = [[CustomAnnotation alloc]init];
annotation.title = title;
annotation.subtitle = #"This is a subtitle";
[annotation setCoordinate:Location];
annotation.imageName = imageName;
return annotation;
}
and my CustomAnnotation Class:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
NSLog(#"Test");
if([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
if([annotation isKindOfClass:[CustomAnnotation class]]){
CustomAnnotation *customAnnotation = annotation;
static NSString* annotationid = #"Annotation";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationid];
if(!annotationView){
annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationid];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}else{
annotationView.annotation = annotation;
}
annotationView.image = [UIImage imageNamed:customAnnotation.imageName];
return annotationView;
}
return nil;
}
For some reason the viewForAnnotation function is never used. Can anyone help me out here?
Thanks
I would like to know how to change the pin color of an annotation in map kit. Currently Im using the following code.
//King Solomon's Lodge No. 194
CLLocationCoordinate2D kingsolomons;
kingsolomons.latitude = 38.052041;
kingsolomons.longitude = -78.683218;
Annotation *kingsolomonslodge = [[Annotation alloc] init];
kingsolomonslodge.coordinate = kingsolomons;
kingsolomonslodge.title = #"King Solomon's Lodge No. 194";
kingsolomonslodge.subtitle = #"Charlottesville, VA";
[self.myMapView addAnnotation:kingsolomonslodge];
I have googled this question a few times but Im unsure on how to implement this into the current code that I have.
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if (annotation == mapview.userLocation)
return nil;
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapview dequeueReusableAnnotationViewWithIdentifier: #"asdf"];
if (pin == nil)
pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: #"asdf"] autorelease];
else
pin.annotation = annotation;
// NSLog(#"%#",annotation.title);
NSString *titlename=#"xyz";
if ([annotation.title isEqualToString:titlename]) {
pin.pinColor = MKPinAnnotationColorGreen;
// pin.image=[UIImage imageNamed:#"arrest.png"] ;
}
else{
pin.pinColor= MKPinAnnotationColorPurple;
}
pin.userInteractionEnabled = YES;
UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeCustom];
// //pin.image=[UIImage imageNamed:#"arrest.png"] ;
pin.rightCalloutAccessoryView = disclosureButton;
//pin.pinColor = MKPinAnnotationColorRed;
pin.animatesDrop = YES;
[pin setEnabled:YES];
[pin setCanShowCallout:YES];
return pin;
}
You can use pinColor property if MKAnnotation class.
kingsolomonslodge.pinColor = MKPinAnnotationColorGreen;
Another way is you can use image instead of the default pin using viewForAnnotation: delegate:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[yourAnnotationLocation class]])
{
MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:#"yourImage.png"];//here we use a nice image instead of the default pins
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
{
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
try this man...
kingsolomonslodge.pinColor = AnnotationColorRed;
let me know whether it is workihg or not
happy coding!!!!
If you want to apply custom color you can add image also.
MKAnnotationView *pinView = nil;
pinView.image = [UIImage imageNamed:#"pinks.jpg"];
Since iOS 9:
kingsolomonslodge.pinTintColor = UIColor.greenColor;
Hi can some1 plz help me....
The problem is this: Everything seems alright.. i am able to push to another page once i tap on the detailButton. However, the page which i am able to push to is always only a view without any values passed into the labels. All my labels in the view have nothing inside.. Am i doing something wrong or any wrong concept here?
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
BOOL isRed = NO;
//BOOL isPurple = YES;
if([annotation isKindOfClass:[MyAnnotation2 class]])
isRed = YES;
MKPinAnnotationView *pinView = nil;
if(isRed) {
static NSString *redPin = #"redPin";
pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:redPin];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:redPin] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = detailButton;
}
else{
pinView.annotation = annotation;
}
}
else {
static NSString *greenPin = #"greenPin";
pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:greenPin];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:greenPin] autorelease];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = detailButton;
}
}
return pinView;
}
//
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped");
if (self.patientDetailsViewController == nil) {
self.patientDetailsViewController = [[[PatientDetailsViewController alloc] initWithNibName:#"PatientDetailsViewController" bundle:nil] autorelease];
}
MyAnnotation2 *selectedObject = (MyAnnotation2 *)view.annotation;
_patientDetailsViewController.nric = selectedObject.title;
NSLog(#"%#",_patientDetailsViewController.nric);
[self.navigationController pushViewController:_patientDetailsViewController animated:YES];
}
Don't use your own target/action and tagging for the callout accessory button.
Instead, use the MKMapViewDelegate method calloutAccessoryControlTapped:. Remove the addTarget line and implement the delegate method.
In that delegate method, you can access the annotation tapped using:
MyAnnotation2 *selectedObject = (MyAnnotation2 *)view.annotation;
In my application i want to display custom view(with buttons) in the case of user touches annotation on map(standard pin).
i know that i can subclass MKAnnotationView and change the view of pin. but how can i change the look of Additional information view, that appears when user touches pin(by default it displays title and subtitle of MKAnnotation object).
how can i do this?
Thanks.
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id )annotation
{
MKPinAnnotationView *pinView = nil;
static NSString *defaultPinID = #"ReusedPin";
pinView = (MKPinAnnotationView*)[mVdequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
if (((PinAnnotationView*)annotation).tag == 0 )
{
pinView.pinColor = MKPinAnnotationColorPurple;
}
else {
pinView.pinColor = MKPinAnnotationColorRed;
}
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
UIImageView *pinImageView = [[UIImageView alloc] initWithFrame:CGRectMake(-5, 0, 34, 34)];
UIImage *pinImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"icon" ofType:#"png"]];
pinImageView.image = pinImage;
[pinImage release];
[pinView addSubview:pinImageView];
[pinImageView release];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
btn.tag = ((PinAnnotationView*)annotation).tag;
pinView.rightCalloutAccessoryView = btn;
return pinView;
}
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
if ( control.tag !=0) {
ShowProviderDetailVC *viewControlle = [[ShowProviderDetailVC alloc]initWithNibName:#"ShowProviderDetailVC" bundle:nil];
viewControlle.lastViewName = #"SearchView";
for (NSMutableDictionary* dict in globalLocArray) {
if ( control.tag ==[[dict valueForKey:#"ID"] intValue] )
{
viewControlle.providerInfoDict = dict;
}
}
[self.navigationController pushViewController:viewControlle animated:YES];
[viewControlle release];
}
Custom callout bubble can be displayed by making sub class of UIView Class.
You can check these links.
http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-1/
http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-2/
I've been following this tutorial to show custom annotation callout bubbles.
It works perfectly if you have only one annotation with a custom annotationview.
However, I need to have more on my map, and I have troubles switching from a custom annotationview to another one. If I click on another pin when having selected already one and would like to make appear the new custom annotationview, it doesn't work. I have first to click somewhere else random on the mapview. I guess I have something to work on in DidDeselect Method, but I'm not sure...
How would you solve such a problem?
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
if (self.calloutAnnotation && [view.annotation isKindOfClass:[MyHomeAnnotation class]]) {
[self.mapView removeAnnotation: self.calloutAnnotation];
}
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if ([view.annotation isKindOfClass:[MyHomeAnnotation class]]) {
if (self.calloutAnnotation == nil) {
self.calloutAnnotation = [[CalloutMapAnnotation alloc] initWithLatitude:view.annotation.coordinate.latitude
andLongitude:view.annotation.coordinate.longitude];
} else {
self.calloutAnnotation.latitude = view.annotation.coordinate.latitude;
self.calloutAnnotation.longitude = view.annotation.coordinate.longitude;
}
[self.mapView addAnnotation:self.calloutAnnotation];
self.selectedAnnotationView = view;
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (annotation == self.calloutAnnotation) {
CalloutMapAnnotationView *calloutMapAnnotationView = (CalloutMapAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:#"CalloutAnnotation"];
if (!calloutMapAnnotationView) {
calloutMapAnnotationView = [[[CalloutMapAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"CalloutAnnotation"] autorelease];
calloutMapAnnotationView.contentHeight = 78.0f;
UIImage *asynchronyLogo = [UIImage imageNamed:#"cykelrød1.png"];
UIImageView *asynchronyLogoView = [[[UIImageView alloc] initWithImage:asynchronyLogo] autorelease];
asynchronyLogoView.frame = CGRectMake(5, 2, asynchronyLogoView.frame.size.width, asynchronyLogoView.frame.size.height);
[calloutMapAnnotationView.contentView addSubview:asynchronyLogoView];
}
calloutMapAnnotationView.parentAnnotationView = self.selectedAnnotationView;
calloutMapAnnotationView.mapView = self.mapView;
return calloutMapAnnotationView;
} else if ([annotation isKindOfClass:[MyHomeAnnotation class]]) {
MKPinAnnotationView *annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"CustomAnnotation"] autorelease];
annotationView.canShowCallout = NO;
annotationView.pinColor = MKPinAnnotationColorGreen;
return annotationView;
}else if ([annotation isKindOfClass:[MyMapAnnotation class]]) {
MKPinAnnotationView *annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"NormalAnnotation"] autorelease];
annotationView.canShowCallout = YES;
annotationView.pinColor = MKPinAnnotationColorPurple;
return annotationView;
}
return nil;
}
Here are my solution, I use latitude and longitude to distinguish which callout should be remove from mapview. Hope this will be help.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
NSLog(#"didSelectAnnotationView:%f", view.annotation.coordinate.latitude);
if (self.calloutAnnotation == nil) {
CalloutMapAnnotation *tempCallout = [[CalloutMapAnnotation alloc]
initWithLatitude:view.annotation.coordinate.latitude
andLongitude:view.annotation.coordinate.longitude];
self.calloutAnnotation = tempCallout;
[tempCallout release];
} else {
//remove callout when callout already exist
[self.myMapView removeAnnotation: self.calloutAnnotation];
self.selectedAnnotationView = nil;
//reposition
self.calloutAnnotation.latitude = view.annotation.coordinate.latitude;
self.calloutAnnotation.longitude = view.annotation.coordinate.longitude;
}
[self.myMapView addAnnotation:self.calloutAnnotation];
self.selectedAnnotationView = view;
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
NSLog(#"didDeselectAnnotationView:%f", view.annotation.coordinate.latitude);
//use the latitude and longitude to avoid remove twice
if (self.calloutAnnotation &&
self.selectedAnnotationView.annotation.coordinate.latitude == view.annotation.coordinate.latitude &&
self.selectedAnnotationView.annotation.coordinate.longitude == view.annotation.coordinate.longitude
) {
[self.myMapView removeAnnotation: self.calloutAnnotation];
self.selectedAnnotationView = nil;
self.calloutAnnotation.isAddtoMap = NO;
}
}