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

时间:2014-04-23 00:24:43

标签: ios mapkit mkannotationview

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

我有一个标签栏应用程序。在一个选项卡上,我输入点,在另一个选项卡上,点显示在地图上。引脚应根据点的类型而不同。

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

所以,这是代码:

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

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

1 个答案:

答案 0 :(得分:3)

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

当重新显示注释时,它们会重复使用带有先前注释图像的视图。视图中的image属性在重新用于其他注释时应该不会更新。

viewForAnnotation委托方法中,此代码看起来不对:

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

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

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

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

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

更新后的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;
}