【问题标题】:Map annotation swapping from displaying image to default pin randomly地图注释从显示图像随机交换到默认图钉
【发布时间】:2015-05-12 10:13:44
【问题描述】:

当通过模拟器测试地图时,我注意到一些注释显示默认图钉而不是自定义图像。当我回到应用程序主菜单并再次进入地图视图时,不同的注释会发生同样的事情。

此代码显示了我拥有的 20 个注释中的 4 个,它们都使用相同的代码。

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


     }

【问题讨论】:

  • 这个问题是不是来自if和else?
  • 不需要为了设置注解坐标而创建和设置区域。你可以做ann2.coordinate = CLLocationCoordinate2DMake(55.705609, 13.195707);。在添加所有注释后仅调用一次 setRegion(或 showAnnotations)以在地图上显示该区域。

标签: ios mapkit mkannotationview


【解决方案1】:

由于此代码,您“随机”获得默认引脚:

MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];

if (annotationView)
    return nil;

这段代码的意思是,如果dequeueReusableAnnotationViewWithIdentifier: 返回一个视图(即,如果annotationView 不是 nil),则从委托方法返回nil


当您从 viewForAnnotation 委托方法返回 nil 时,地图视图会执行以下操作:

  • 如果注解的类型为MKUserLocation,则会显示默认的蓝点。
  • 如果注解不是MKUserLocation,它将显示默认的红色大头针。

你可能的意思是:

MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];

if (annotationView)
    return annotationView;

然而,这将产生一个新问题,因为如果 dequeue 返回一个视图(以前用于不同 注释),出队视图的image 可能与当前annotation 应使用的图像不匹配。

因此,当您缩放和平移地图时,注释图像会“随机”切换。

viewForAnnotation 中的正确做法是:

  1. 使用dequeueReusableAnnotationViewWithIdentifier: 获取对视图的引用,如果返回nil,则创建一个新视图。仅在创建新视图时设置所有注释通用的视图属性。
  2. 使用在步骤 1 中获得的视图引用,设置特定于当前annotation 的视图属性。如果正在使用出队视图,请同时更新其 annotation 属性。

例子:

- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
    if (! [annotation isKindOfClass:[testmap class]])
    {
        //If annotation is NOT a "testmap" (eg. MKUserLocation),
        //return nil so map view displays default view for 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 to all annotations...
        annotationView.canShowCallout = YES;
        UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        //Do not use addTarget with a custom method for callout accessories.
        //Instead, use the calloutAccessoryControlTapped delegate method shown below.
        annotationView.rightCalloutAccessoryView = rightButton;
        annotationView.draggable = YES;
    }
    else {
        //reusing a view, update its annotation to current...
        annotationView.annotation = annotation;
    }

    //AFTER we have a 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 will always be same as `name` property then
     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 for '%@' tapped", tm.name);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    相关资源
    最近更新 更多