0

长按时我发现了一些奇怪的行为MKPointAnnotation

我这样创建我的图钉:

MKPointAnnotation *activeTRPoint = [[MKPointAnnotation alloc] init];
CLLocation *coord = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
activeTRPoint.coordinate = coord.coordinate;
activeTRPoint.title = @"Title";
activeTRPoint.subtitle = @"subtitle";
//Added tag
[map addAnnotation:activeTRPoint];
[[map viewForAnnotation:activeTRPoint] setTag:1];
UIImage *im = [UIImage imageNamed:@"pin_icon.png"];
[[map viewForAnnotation:activeTRPoint] setImage:im];

因此,当我长按引脚时,它会变为红色引脚(默认)。你知道为什么会这样吗?

更新:为进一步调查添加了 viewForAnnotation 方法

- (MKAnnotationView *) mapView:(MKMapView *)mapView1 viewForAnnotation:(id <MKAnnotation>) annotation
{
    if(annotation != map.userLocation){
        // This is not the users location indicator (the blue dot)
        MKAnnotationView *view = [map dequeueReusableAnnotationViewWithIdentifier:@"myAnnotationIdentifier"];
        BOOL isCustomPin = [subtitles containsObject:((MKPointAnnotation*)annotation).subtitle];
        if (!view && isCustomPin == NO) {
            // Creating a new annotation view, in this case it still looks like a pin
            MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotationIdentifier"];
            annView.pinColor = MKPinAnnotationColorGreen;
            view = annView;
            view.canShowCallout = YES; // So that the callout can appear
            UIButton *btnViewVenue = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            [btnViewVenue addTarget:self action:@selector(pinTouched:) forControlEvents:UIControlEventTouchUpInside];
            view.rightCalloutAccessoryView = btnViewVenue;
            view.enabled = YES;
            view.canShowCallout = YES;
            view.multipleTouchEnabled = NO;
        }else{
            UIImage *im = [UIImage imageNamed:@"pin_icon.png"];
            [view setImage:im];
        }
        return view;
    }else{
        mapView1.userLocation.title = [Lang get:@"USER_CURRENT_LOCATION"];
        mapView1.userLocation.subtitle = @"";
        [mapView1 setTag:999];
        return nil;
    }
}
4

1 回答 1

2

在所示的viewForAnnotation委托方法中,实际创建的唯一类型的注释视图(alloc+init)是MKPinAnnotationView.

isCustomPinisYES时,原样的代码永远不会真正创建 an MKAnnotationView,因此最终会引用 a view

  • 要么是nil因为dequeue没有返回任何东西,要么
  • 是一个,MKPinAnnotationView因为这是有史以来唯一创建的视图类型,并且出队返回以前使用过的视图。

所以什么isCustomPin时候YES

  • 它返回一个nil视图,地图视图将其解释为“显示默认红色引脚”(基本上是红色MKPinAnnotationView),或者
  • 它返回一个绿色MKPinAnnotationView

在任何情况下,代码总是返回一个MKPinAnnotationView,地图视图通常会忽略该image属性并根据pinColor.


要解决这个问题,您必须将“自定义图像”引脚的创建和重用与“绿色引脚”分开。例如:

BOOL isCustomPin = [subtitles containsObject:((MKPointAnnotation*)annotation).subtitle];

if (isCustomPin)
{
    //Put dequeue and alloc+init of MKAnnotationView here.
    //NOTE: Use a DIFFERENT re-use identifier for "custom image" pins.
    //Eg. Use "myCustomIdentifier" -- not "myAnnotationIdentifier"
}
else
{
    //Put dequeue and alloc+init of MKPinAnnotationView here.
    //NOTE: Use a DIFFERENT re-use identifier from "custom image" pins.
    //That is, use "myAnnotationIdentifier" -- not "myCustomIdentifier".
}


一些单独的,可能不相关的问题:

  • 用于确定的逻辑isCustomPin看起来值得怀疑。最好创建一个自定义注释类并检查是否annotation属于该类型,而不是在某个外部数组中查找注释。
  • 注释视图出队后,您应该将视图的annotation属性设置为当前视图,annotation否则视图将使用以前的注释属性。
  • 应该不需要使用标签(我不推荐它)。用户位置注解可以通过其类来识别,MKUserLocation在方法中,您可以使用 的属性pinTouched:获取选中的注解。selectedAnnotationsMKMapView


顺便说一句,您还应该在调用addAnnotation.

于 2013-07-24T13:48:03.293 回答