MapKit changes annotation view order when map is scrolled in XCode 4.6 -


i experienced ios developer, has stumped me. simultaneously submitting problem report apple.

i'm adding annotations mkmapkit map (xcode 4.6). each annotation myannotation class; myannotation defines property, location_id, use keep track of annotation.

the problem simple: want myannotation location_id of -1 appear in front of else.

to this, overriding mapview:didaddannotationviews: in mkmapviewdelegate:

-(void)mapview:(mkmapview *)mapview didaddannotationviews:(nsarray *)views {   // loop through newly added views, arranging them (z-index) (mkannotationview* view in views) {      // check location id     if([view.annotation iskindofclass:[myannotation class]] && [((myannotation*)(view.annotation)).location_id intvalue]==-1 ) {          // -1: bring front         [[view superview] bringsubviewtofront:view];         nslog(@"to front: %@",((myannotation*)view.annotation).location_id);      } else {          // else: send         [[view superview] sendsubviewtoback:view];         nslog(@"to back: %@",((myannotation*)view.annotation).location_id);     } } } 

this works fine. have "add" button adds annotation random location near center of map. each time push "add" button, new annotation appears; nothing hides annotation location_id of -1.

** until ** scroll!

as start scrolling, of annotations rearranged (z-order) , careful stacking no longer applies.

the confusing thing is, i've done icon order stacking before no problem whatsoever. i've created brand new, single view app test problem out; sending mkannotationview items or front works until scroll. there nothing else in skeleton app except code described above. i'm wondering if there kind of bug in latest mapkit framework.

the original problem in trying add new annotations when user scrolled (mapview:regiondidchangeanimated:). annotation adds; mapview:didaddannotationviews: code fires; , order scrambled unseen hand in framework (presumably scroll completes).

in case you're interested, here viewforannotation:

-(mkannotationview*)mapview:(mkmapview *)mapview viewforannotation:(id<mkannotation>)annotation {   // a91location? if([annotation iskindofclass:[myannotation class]]){      myannotation* ann=(myannotation*)annotation;      nslog(@"viewforannotation a91location id %@",ann.location_id);       if([ann.location_id intvalue]==-1){          // if id -1, use green pin         mkpinannotationview* green_pin=[[mkpinannotationview alloc] initwithannotation:annotation reuseidentifier:nil];         green_pin.pincolor=mkpinannotationcolorgreen;         green_pin.enabled=no;         return green_pin;      } else {          // otherwise, use default (red) pin         mkpinannotationview* red_pin=[[mkpinannotationview alloc] initwithannotation:annotation reuseidentifier:nil];         red_pin.enabled=no;         return red_pin;     } }   // else return nil;   } 

and class:

@interface myannotation : nsobject <mkannotation>  @property (strong, nonatomic, readonly) nsnumber* location_id; @property (strong, nonatomic, readonly) nsstring*  name; @property (strong, nonatomic, readonly) nsstring*  description; @property (nonatomic) cllocationcoordinate2d coordinate;  -(id) initwithid:(nsnumber*)location_id name: (nsstring*) name description:(nsstring*) description location:(cllocationcoordinate2d) location;  // mkannotation protocol... return name , description, respectively -(nsstring*)title; -(nsstring*)subtitle;  @end 

could possibly try following work around:

1) remove code in mapview:didaddannotationviews:

2) pickup when map moved or pinched (i assume consider scroll right?) - gestures rather mapview regionchanged have had bad experiences such unexplained behaviour latter.

//recognise paning gesture fire diddragmap method uipangesturerecognizer* panrec = [[uipangesturerecognizer alloc] initwithtarget:self     action:@selector(diddragmap:)]; [panrec setdelegate:self]; [self.mapview addgesturerecognizer:panrec];  //recognise pinching gesture fire didpinchmap method uipinchgesturerecognizer *pinchrec = [[uipinchgesturerecognizer alloc]initwithtarget:self action:@selector(didpinchmap:)]; [pinchrec setdelegate:self]; //[pinchrec setdelaystouchesbegan:yes]; [self.mapview addgesturerecognizer:pinchrec];  //recognise doubletap uitapgesturerecognizer *doubletaprec = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(didpinchmap:)]; [doubletaprec setdelegate:self]; doubletaprec.numberoftapsrequired = 2; [self.mapview addgesturerecognizer:doubletaprec]; 

3) write custom "plotannotations" function show annotations. function loop through annotations , save them in array "annotationstoshow" ordered location id desc location_id -1 added last. use [self.mapview addannotations:annotationstoshow]; display them.

4) call plotannotations in gesturerecognizer functions

- (void)diddragmap:(uigesturerecognizer*)gesturerecognizer {     if (gesturerecognizer.state == uigesturerecognizerstateended){         [self plotannotations];     } }  - (void)didpinchmap:(uigesturerecognizer*)gesturerecognizer {     if (gesturerecognizer.state == uigesturerecognizerstateended){         [self plotannotations];     } } 

5) may need delete annotations before displaying new ones in 3) [self.mapview removeannotations:annotationstoremove];


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -