iPhone MapKit 问题:viewForAnnotation 设置 pinColor 不一致?

Posted

技术标签:

【中文标题】iPhone MapKit 问题:viewForAnnotation 设置 pinColor 不一致?【英文标题】:iPhone MapKit problems: viewForAnnotation inconsistently setting pinColor? 【发布时间】:2010-06-10 03:58:42 【问题描述】:

我正在尝试设置一个地图,根据相关位置的类型/类别显示不同的图钉颜色。我知道这是一件很常见的事情,但我无法让 viewForAnnotation 委托持续更新/设置图钉颜色。 我有一个 showThisLocation 函数,它基本上循环遍历 AddressAnnotations 列表,然后基于注释类(公交车站、医院等)我设置了一个


if( myClass == 1)
 [defaults setObject:@"1" forKey:@"currPinColor"];
 [defaults synchronize];
 NSLog(@"Should be %@!", [defaults objectForKey:@"currPinColor"]);
 else if( myClass ==2 )
 [defaults setObject:@"2" forKey:@"currPinColor"];
 [defaults synchronize];
 NSLog(@"Should be %@!", [defaults objectForKey:@"currPinColor"]);

[_mapView addAnnotation:myCurrentAnnotation];

那么我的 viewForAnnotation 委托看起来像这样,


- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
    if( annotation == mapView.userLocation ) return nil; 

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    MKPinAnnotationView *annView = nil;
    annView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"currentloc"];
    if( annView == nil )
        annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"];
    

    annView.pinColor =  [defaults integerForKey:@"currPinColor"];
    NSLog(@"Pin color: %d", [defaults integerForKey:@"currPinColor"]);
    annView.animatesDrop=TRUE;
    annView.canShowCallout = YES;
    annView.calloutOffset = CGPointMake(-5, 5);
    return annView;

问题在于,尽管“if”块中的 NSLog 语句始终确认颜色已设置,但委托有时但并不总是以正确的颜色结束。我还注意到,通常发生的情况是,第一次搜索新位置会将所有引脚设置为“if”块中的最后一种颜色,但再次搜索相同位置会将引脚设置为正确的颜色。

我怀疑我不应该以这种方式使用 NSUserDefaults,但我也尝试为 MKAnnotation 创建自己的子类,其中包括一个附加属性“currentPinColor”,虽然这允许我设置“currentPinColor”,但当我试图从委托方法访问“currentPinColor”,编译器抱怨它对“currentPinColor 与 MKAnnotation.我猜很公平,但后来我尝试修改委托方法,


- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MyCustomMKAnnotation>)annotation 

而不是默认的


- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 

此时编译器抱怨它对这个委托上下文中的 MyCustomMKAnnotation 协议一无所知。

设置委托方法和/或 MyCustomMKAnnotation 的正确方法是什么,或者实现一致的 pinColor 设置的正确方法是什么。我对在这里尝试的东西几乎没有想法。

【问题讨论】:

【参考方案1】:

我解决了自己的问题。有时仅仅提出问题就足够了! 问题是我试图访问我的 MKAnnotation 委托的方式。

发帖后我碰巧看到了这两个相关的帖子,

MKPinAnnotationView: Are there more than three colors available?

Mapkit issue in finding annotation current position

用户 Cannonade 对第一篇帖子的回答建议


- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
   
    // ... get the annotation delegate and allocate the MKAnnotationView (annView)
    if ([annotationDelegate.type localizedCaseInsensitiveCompare:@"NeedsBluePin"] == NSOrderedSame)
    
        UIImage * image = [UIImage imageNamed:@"blue_pin.png"];
        UIImageView *imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
        [annView addSubview:imageView];
    
    // ...

但是我的问题是我不知道如何获得委托,并且它漂浮在上述 sn-p 的省略号部分的某个地方。第二个帖子的答案,也是由用户 Cannonade 提供的,填补了这个缺失的部分,


- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

    AnnotationDelegate * delegate = (AnnotationDelegate*)view.annotation;
    // do stuff with delegate.position;

将这两个sn-ps放在一起产生了预期的结果,最终解决了我的问题。

工作 viewForAnnotation 委托方法看起来像,


- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
    if( annotation == mapView.userLocation ) return nil; 
    AddressAnnotation *delegate = annotation;  //THIS CAST WAS WHAT WAS MISSING!
    MKPinAnnotationView *annView = nil;
    annView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"currentloc"];
    if( annView == nil )
        annView = [[MKPinAnnotationView alloc] initWithAnnotation:delegate reuseIdentifier:@"currentloc"];
    

    if ([delegate.classPinColor localizedCaseInsensitiveCompare:@"green"] == NSOrderedSame) 
        annView.pinColor = MKPinAnnotationColorGreen;
    else if ([delegate.classPinColor localizedCaseInsensitiveCompare:@"purple"] == NSOrderedSame)
        annView.pinColor = MKPinAnnotationColorPurple;
    else if ([delegate.classPinColor localizedCaseInsensitiveCompare:@"red"] == NSOrderedSame)
        annView.pinColor = MKPinAnnotationColorRed;
    
    annView.animatesDrop=TRUE;
    annView.canShowCallout = YES;
    annView.calloutOffset = CGPointMake(-5, 5);
    return annView;

希望这对其他人有所帮助。

谢谢炮弹!

【讨论】:

为什么我需要 2 天才能回答我自己的问题? 第 3 行的 AddressAnnotation 是什么?

以上是关于iPhone MapKit 问题:viewForAnnotation 设置 pinColor 不一致?的主要内容,如果未能解决你的问题,请参考以下文章

苹果 mapkit 在中国可以在 iPhone 设备上使用吗

iPhone 的 MapKit 是不是可以叠加平铺

iPhone MapKit 错误

创建 Iphone MapKit 显示用户位置环动画

较小的 MapKit 缩放间隔 iPhone

iPhone Mapkit 蓝点/用户位置区域缩放问题