显示自定义多个引脚显示位置错误的引脚

这个问题已经困扰了我几个星期了!

我有一个标签栏应用程序。 在一个选项卡上input点,在另一个选项卡上,点显示在地图上。 针脚应该不同,取决于点的types。

我面临的问题是,每当我从一个标签切换到另一个标签时,图钉图像就会从应该更改为其他图像。 例如,如果我在地图上有四个点,三个显示为一个圆形,一个显示为三angular形,则三angular形将从一个点移动到另一个点。 图像似乎随机改变。

所以,这是代码:

ViewController.m

-(void) viewWillAppear:(BOOL)animated { // Select the type of map if (isMapSelected == NO) { self.mapView.mapType = MKMapTypeSatellite; } else { self.mapView.mapType = MKMapTypeStandard; } // Add region to the map (center and span) [self addRegion]; // Removing old annotation [self.mapView removeAnnotations:mapLocations]; // Initializing arrays for the annotations mapLocations = [[NSMutableArray alloc]init]; [self addAnnotation]; } -(void) addAnnotation { CLLocationCoordinate2D mapLocation; IGAMapAnnotation *mapAnnotation; // Calculate how many points are included NSInteger numberOfPoints = [coordinatesTempArray count]; // Annotations will be added only of the flight plan includes at least one point if (numberOfPoints > 0) { // Trying to add coordinates from the array of coordinates for (NSInteger i=0; i < ([coordinatesTempArray count]); i++) { mapAnnotation = [[IGAMapAnnotation alloc]init]; // Taking a point in the array and getting its coordinates self.mapCoordinates = [coordinatesTempArray objectAtIndex:i]; // Getting a point in the array and getting its lattitude and longitude self.mapLatitude = [[self.mapCoordinates objectAtIndex:0]doubleValue]; self.mapLongitude = [[self.mapCoordinates objectAtIndex:1]doubleValue]; // Assigning the point coordinates to the coordinates to be displayed on the map mapLocation.latitude = self.mapLatitude; mapLocation.longitude = self.mapLongitude; // Adding coordinates and title to the map annotation mapAnnotation.coordinate = mapLocation; mapAnnotation.title = [navaidNamesTempArray objectAtIndex:i]; mapAnnotation.subtitle = nil; mapAnnotation.navaidType = [navaidTypesTempArray objectAtIndex:i]; // Adding the annotation to the array that will be added to the map [mapLocations addObject:mapAnnotation]; } // Adding annotations to the map [self.mapView addAnnotations:mapLocations]; } } -(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if([annotation isKindOfClass:[IGAMapAnnotation class]]) { IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation; MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"]; if (annotationView == nil) annotationView = myLocation.annotationView; else annotationView.annotation = annotation; return annotationView; } else return nil; } 

IGAMapAnnotation.m

 @synthesize coordinate = _coordinate; @synthesize title = _title; @synthesize subtitle = _subtitle; @synthesize type = _type; // Tried to have this init method but was never able to make it work. Without it, the program crashes too!!!! -(id)initWithTitle:(NSString *)newTitle Type:(NSString *)type Location:(CLLocationCoordinate2D) newCoordinate { self = [super init]; if (self) { _title = newTitle; _coordinate = newCoordinate; _type = type; } return self; } -(MKAnnotationView *) annotationView { MKAnnotationView *annotationView = [[MKAnnotationView alloc]initWithAnnotation:self reuseIdentifier:@"IGAMapAnnotation"]; annotationView.enabled = YES; annotationView.canShowCallout = YES; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; if ([self.type isEqual: @"A"] || [self.type isEqual: @"B"] || [self.type isEqual: @"C"]) { annotationView.image = [UIImage imageNamed:@"circle.png"]; } else if ([self.type isEqual: @"D"]) { annotationView.image = [UIImage imageNamed:@"triangle.png"]; } else if ([self.type isEqual: @"E"]) { annotationView.image = [UIImage imageNamed:@"square.png"]; } else { annotationView.image = [UIImage imageNamed:@"oval.png"]; } return annotationView; } @end 

就是这个。 到目前为止,这种行为对我来说毫无意义。 谢谢你的帮助!

这听起来像一个注解视图重用问题。

当注释重新显示时,它们将重复使用以前注释的图像。 当视图中的image属性被重新用于另一个注释时,它不会被更新。

viewForAnnotation委托方法,这段代码看起来是错误的:

 MKAnnotationView *annotationView = [mapView dequeue... if (annotationView == nil) annotationView = myLocation.annotationView; else annotationView.annotation = annotation; 

如果出dequeue返回一个视图(即,可能已经为不同types的注释创build的先前创build的视图),则其annotation属性被更新,但是其image属性不被更新。

现有代码只在创build新的注释视图时设置image属性(当dequeue返回nil )。

现在,注释视图创build和image设置代码位于注释模型IGAMapAnnotation 。 最好是创build一个自定义的MKAnnotationView类,当它的annotation属性更新时,它自动更新image属性。

然而,另一种方法是将所有逻辑放在viewForAnnotation委托方法本身中(并从IGAMapAnnotation类中移除annotationView方法)。

更新的viewForAnnotation委托方法的示例:

 -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if (! [annotation isKindOfClass:[IGAMapAnnotation class]]) { //return default view if annotation is NOT of type IGAMapAnnotation... return nil; } MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"IGAMapAnnotation"]; //these properties don't change per annotation //so they can be set only when creating a new view... annotationView.enabled = YES; annotationView.canShowCallout = YES; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; } else { annotationView.annotation = annotation; } //whether we are using a completely new view or a re-used view, //set the view's image based on the current annotation... IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation; if ([myLocation.type isEqual: @"A"] || [myLocation.type isEqual: @"B"] || [myLocation.type isEqual: @"C"]) { annotationView.image = [UIImage imageNamed:@"circle.png"]; } else if ([myLocation.type isEqual: @"D"]) { annotationView.image = [UIImage imageNamed:@"triangle.png"]; } else if ([myLocation.type isEqual: @"E"]) { annotationView.image = [UIImage imageNamed:@"square.png"]; } else { annotationView.image = [UIImage imageNamed:@"oval.png"]; } return annotationView; }