ios - Map annotation swapping from displaying image to default pin randomly -
when map tested through simulator notice annotations display default pin instead of customized image. when go apps home menu , enter mapview again same thing happens different annotations.
this code present 4 annotations out of 20 have uses same code.
-(void)viewdidload { [super viewdidload]; _locationmanager = [[cllocationmanager alloc] init]; [mapview setdelegate:self]; [mapview setmaptype:mkmaptypestandard]; [mapview setzoomenabled:yes]; [mapview setscrollenabled:yes]; mkcoordinateregion test1 = { {0.0, 0.0} , {0.0, 0.0} }; test1.center.latitude = 55.705609; test1.center.longitude = 13.195707; [mapview setregion:test1 animated:yes]; testmap *ann2 = [[testmap alloc] init]; ann2.title = @"test1"; ann2.subtitle = @"klicka här för mer info"; ann2.coordinate = test1.center; ann2.name = @"test1"; [mapview addannotation:ann2]; mkcoordinateregion test2 = { {0.0, 0.0} , {0.0, 0.0} }; //ändra ner test2.center.latitude = 55.710113; test2.center.longitude = 13.213500; [mapview setregion:test2 animated:yes]; testmap *ann3 = [[testmap alloc] init]; ann3.title = @"test2"; ann3.subtitle = @"klicka här för mer info"; ann3.coordinate = test2.center; ann3.name = @"test2"; [mapview addannotation:ann3]; mkcoordinateregion test3 = { {0.0, 0.0} , {0.0, 0.0} }; test3.center.latitude = 55.708981; test3.center.longitude = 13.197266; [mapview setregion:test3 animated:yes]; testmap *ann4 = [[testmap alloc] init]; ann4.title = @"test3"; ann4.subtitle = @"klicka här för mer info"; ann4.coordinate = test3.center; ann4.name = @"test3"; [mapview addannotation:ann4]; mkcoordinateregion test4 = { {0.0, 0.0} , {0.0, 0.0} }; //ändra ner test4.center.latitude = 55.705170; test4.center.longitude = 13.191277; [mapview setregion:test4 animated:yes]; testmap *ann5 = [[testmap alloc] init]; ann5.title = @"test4"; ann5.subtitle = @"klicka här för mer info"; ann5.coordinate = test4.center; ann5.name = @"test4"; [mapview addannotation:ann5]; } - (mkannotationview *)mapview:(mkmapview *)mapview viewforannotation:(id <mkannotation>)annotation { if ([annotation iskindofclass:[mkuserlocation class]]) return nil; static nsstring* annotationidentifier = @"annotationidentifier"; mkannotationview *annotationview = [mapview dequeuereusableannotationviewwithidentifier:annotationidentifier]; if(annotationview) return nil; else { mkannotationview *annotationview = [[mkannotationview alloc] initwithannotation:annotation reuseidentifier:annotationidentifier]; annotationview.canshowcallout = yes; nsstring* thismodelname = ((testmap*)annotation).name; if ([thismodelname isequaltostring:@"test1"]) { annotationview.image = [uiimage imagenamed:@"test1"]; uibutton* rightbutton = [uibutton buttonwithtype:uibuttontypedetaildisclosure]; [rightbutton settitle:annotation.title forstate:uicontrolstatenormal]; annotationview.rightcalloutaccessoryview = rightbutton; annotationview.canshowcallout = yes; annotationview.draggable = yes; annotationview.highlighted = yes; return annotationview; } else if ([thismodelname isequaltostring:@"test2"]) { annotationview.image = [uiimage imagenamed:@"test2"]; uibutton* rightbutton = [uibutton buttonwithtype:uibuttontypedetaildisclosure]; [rightbutton addtarget:self action:@selector(mybutton:) forcontrolevents:uicontroleventtouchupinside]; [rightbutton settitle:annotation.title forstate:uicontrolstatenormal]; annotationview.rightcalloutaccessoryview = rightbutton; annotationview.canshowcallout = yes; annotationview.draggable = yes; annotationview.highlighted = yes; return annotationview; } else if ([thismodelname isequaltostring:@"test3"]) { annotationview.image = [uiimage imagenamed:@"test3"]; uibutton* rightbutton = [uibutton buttonwithtype:uibuttontypedetaildisclosure]; [rightbutton addtarget:self action:@selector(mybutton:) forcontrolevents:uicontroleventtouchupinside]; [rightbutton settitle:annotation.title forstate:uicontrolstatenormal]; annotationview.rightcalloutaccessoryview = rightbutton; annotationview.canshowcallout = yes; annotationview.draggable = yes; annotationview.highlighted = yes; return annotationview; } else if ([thismodelname isequaltostring:@"test4"]) { annotationview.image = [uiimage imagenamed:@"test4"]; uibutton* rightbutton = [uibutton buttonwithtype:uibuttontypedetaildisclosure]; [rightbutton addtarget:self action:@selector(mybutton:) forcontrolevents:uicontroleventtouchupinside]; [rightbutton settitle:annotation.title forstate:uicontrolstatenormal]; annotationview.rightcalloutaccessoryview = rightbutton; annotationview.canshowcallout = yes; annotationview.draggable = yes; annotationview.highlighted = yes; return annotationview; } } return nil; }
you're getting default pins "randomly" because of code:
mkannotationview *annotationview = [mapview dequeuereusableannotationviewwithidentifier:annotationidentifier]; if (annotationview) return nil;
what code says if dequeuereusableannotationviewwithidentifier:
returns view (ie. if annotationview
not nil
), return nil
delegate method.
when return nil
viewforannotation
delegate method, map view following:
- if annotation of type
mkuserlocation
, display default blue dot. - if annotation not
mkuserlocation
, display default red pin.
what meant was:
mkannotationview *annotationview = [mapview dequeuereusableannotationviewwithidentifier:annotationidentifier]; if (annotationview) return annotationview;
however, create new problem because if dequeue
returns view (a view used different annotation), image
of dequeued view might not match image should used current annotation
.
so happen annotation images switch around "randomly" zoom , pan map.
the proper approach in viewforannotation
to:
- get reference view using
dequeuereusableannotationviewwithidentifier:
, if returnsnil
, create new view. set view properties common annotations when creating new view. - using view reference obtained in step 1, set view properties specific current
annotation
. if dequeued view being used, updateannotation
property well.
example:
- (mkannotationview *)mapview:(mkmapview *)mapview viewforannotation:(id <mkannotation>)annotation { if (! [annotation iskindofclass:[testmap class]]) { //if annotation not "testmap" (eg. mkuserlocation), //return nil map view displays default view it... return nil; } static nsstring* annotationidentifier = @"annotationidentifier"; mkannotationview *annotationview = [mapview dequeuereusableannotationviewwithidentifier:annotationidentifier]; if (! annotationview) { annotationview = [[mkannotationview alloc] initwithannotation:annotation reuseidentifier:annotationidentifier]; //set view properties common annotations... annotationview.canshowcallout = yes; uibutton* rightbutton = [uibutton buttonwithtype:uibuttontypedetaildisclosure]; //do not use addtarget custom method callout accessories. //instead, use calloutaccessorycontroltapped delegate method shown below. annotationview.rightcalloutaccessoryview = rightbutton; annotationview.draggable = yes; } else { //reusing view, update annotation current... annotationview.annotation = annotation; } //after have view reference, set annotation-specific properties... nsstring* thismodelname = ((testmap*)annotation).name; if ([thismodelname isequaltostring:@"test1"]) { annotationview.image = [uiimage imagenamed:@"test1"]; } else if ([thismodelname isequaltostring:@"test2"]) { annotationview.image = [uiimage imagenamed:@"test2"]; } else if ([thismodelname isequaltostring:@"test3"]) { annotationview.image = [uiimage imagenamed:@"test3"]; } else if ([thismodelname isequaltostring:@"test4"]) { annotationview.image = [uiimage imagenamed:@"test4"]; } /* if image name same `name` property can use single line instead of if/else statements: annotationview.image = [uiimage imagenamed:thismodelname]; */ return annotationview; } -(void)mapview:(mkmapview *)mapview annotationview:(mkannotationview *)view calloutaccessorycontroltapped:(uicontrol *)control { if ([view.annotation iskindofclass:[testmap class]]) { testmap *tm = (testmap *)view.annotation; nslog(@"button '%@' tapped", tm.name); } }
Comments
Post a Comment