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:

  1. get reference view using dequeuereusableannotationviewwithidentifier: , if returns nil, create new view. set view properties common annotations when creating new view.
  2. using view reference obtained in step 1, set view properties specific current annotation. if dequeued view being used, update annotation 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

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -