显示自定义多个引脚会显示位置错误的引脚 [英] Displaying custom multiple pins shows wrong pins for locations

查看:111
本文介绍了显示自定义多个引脚会显示位置错误的引脚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This problem has been bugging me for a couple of weeks already!

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

I have a tab bar application. On one tab I am entering points, and on another tab, the points are displayed on a map. Pins should be different dependent on the types of points.

我面临的问题是,每当我从一个选项卡切换到另一个选项卡时,固定图像都会从应有的图像变为其他图像.例如,如果我在地图上有四个点,三个点显示为一个圆,一个显示为三角形,则该三角形将从一个点移动到另一个点.图像似乎随机变化.

The problem that I face is that every time I switch from one tab to another, the pin images change from what they should be to other images. For example, if I have four points on the map, three displayed as a circle and one as a triangle, the triangle will be moving around from one point to another. Images seem to change quite randomly.

所以,这是代码:

ViewController.m

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

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

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

This is it. So far, the behaviour makes no sense to me. Thanks for your help!

推荐答案

这听起来像是注释视图的重用问题.

It sounds like an annotation view re-use issue.

重新显示注释时,它们将重新使用带有先前注释图像的视图.视图中的image属性未得到更新,因为它已被重新用于另一个注释.

When the annotations are re-displayed, they are re-using views with the images of previous annotations. The image property in the view is not being updated as it should be when it is re-used for another annotation.

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

In the viewForAnnotation delegate method, this code looks wrong:

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

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

If the dequeue returns a view (ie. a previously-created view that may have been created for an annotation of a different type), its annotation property is updated but its image property is not updated.

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

The existing code only sets the image property when creating a new annotation view (when dequeue returns nil).

现在,注释 view 的创建和image设置代码位于注释 model IGAMapAnnotation中.最好创建一个自定义的MKAnnotationView类,该类在annotation属性更新时自动更新image属性.

Right now, the annotation view creation and image-setting code is in the annotation model class IGAMapAnnotation. It would be better to create a custom MKAnnotationView class that automatically updates the image property whenever its annotation property is updated.

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

However, another alternative is to put all the logic in the viewForAnnotation delegate method itself (and remove the annotationView method from the IGAMapAnnotation class).

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

Example of the updated viewForAnnotation delegate method:

-(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;
}

这篇关于显示自定义多个引脚会显示位置错误的引脚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆