MKAnnotationView缓冲其输入队列吗?

时间:2014-06-13 23:48:14

标签: ios cocoa-touch mkmapview mkannotation

我想根据它们代表的相对时间在UIMapView中显示不同的颜色引脚 但看起来mapView:viewForAnnotation:方法只能在调用它时独立于它。

在我的代码示例中,我已经检索过早期&从文件到self.fileArray的较新位置。 该数组包含称为发现的对象,其中包含(以及其他)年龄属性。 最新的发现开始于年龄@“0”,并且每次重新加载数组以准备采取新的发现 他们分别在年龄上升到@“1”和@“2”,之后他们就被放弃了。

一旦他们接受了他们的新年龄属性,他们就会被发送到mapView:viewForAnnotation:方法 当我遍历fileArray

时,根据他们的新状态显示

实际问题是在跳跃之后。在制定问题时出现了许多有趣的其他答案,但没有一个适用于我的案例

.
.
int size = [self.fileArray count];
for (int idx=(size-1); idx>0; idx--)  // process backwards
    {
        annotationFlag = 0;           // using a global just for now
    self.finding = self.fileArray[idx];
        if ([self.finding.age isEqualToString:@"2"]) {
            [self.fileArray removeObjectAtIndex:idx];
        }

        if ([self.finding.age isEqualToString:@"1"]) {
            self.finding.age = @"2";
            [self.fileArray replaceObjectAtIndex:idx withObject:self.finding];
            annotationFlag = 2;

            // tried here , only displays the newest
        }

        if ([self.finding.age isEqualToString:@"0"]) {
            self.finding.age = @"1";
            [self.fileArray replaceObjectAtIndex:idx withObject:self.finding];
            annotationFlag = 1;

            // tried here, still only displays the same newest 
        }

    }   // end if

//<Breakpoint with Log here> 

    MKPointAnnotation* annotation = [[MKPointAnnotation alloc] init];
    CLLocationCoordinate2D myCoordinate;
    myCoordinate.latitude =[self.finding.myLat doubleValue];
    myCoordinate.longitude=[self.finding.myLong doubleValue];
    annotation.coordinate = myCoordinate;
    [self.mapView addAnnotation:annotation];
}       // end for 
.
.

注释方法是相当标准的,正如大多数人所使用的那样:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation: (MKUserLocation *)userLocation {
_mapView.centerCoordinate = userLocation.location.coordinate;
}


- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {

if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

static NSString *identifier = @"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[ self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
    annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];

//<Breakpoint with Log here>

    switch (annotationFlag) {
        case 1:
        annotationView.pinColor = MKPinAnnotationColorGreen;
            break;
        case 2:
        annotationView.pinColor = MKPinAnnotationColorRed;
            break;
        default:
        annotationView.pinColor = MKPinAnnotationColorPurple;
        break;
    }
    annotationView.animatesDrop = YES;
    annotationView.canShowCallout = NO;
}else {
    annotationView.annotation = annotation;
}
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeSystem]; // UIButtonTypeDetailDisclosure
return annotationView;
}
还在考验的是我的邻居狗的好奇心。每个针脚的针脚应显示不同的颜色   <screenshot>

如果我将NSLog annotationFlag控制到各个点的mapView:viewForAnnotation:似乎是 忽略annotationFlag中的值并仅使用上一次设置的状态,这使我相信它只是在何时起作用 for循环完全完成,而不是迭代。

所以问题是,为什么[self.mapView addAnnotation:annotation]调用不会立即执行。我把它放在for循环中,那里没有发生任何加倍。

LATE EDIT: 使用断点和记录到控制台的组合,如上面的清单所示,并注释掉年龄增加处理导致42个元素的阵列(包括准备丢弃的旧元素),因此要删除42个引脚。

当达到mapView:viewForAnnotation方法时,我必须再次执行42次,并且在第43次所有引脚一次性下降。仔细观察它的相同颜色,以便我可以验证最后使用的颜色不会覆盖任何早期颜色。如果这澄清了问题。

1 个答案:

答案 0 :(得分:1)

无保证 viewForAnnotation将在addAnnotation之后立即调用,或者只会被调用一次。

可以在当前不可见的区域中添加注释,或者用户可以平移或缩放地图,从而使注释返回到视图中。地图视图只需按需要随时调用它。

这是按设计进行的,只是委托方法方法的工作原理。

出于这个原因,您的委托方法的实现通常应该只使用传递给方法的annotation参数作为方法内所有逻辑的基础。它不应该依赖任何外部变量,也不应该对它何时被调用做出广泛的假设。

有关可能更详细解释的其他答案,请参阅:

特别针对您的问题,我建议如下:

  1. 目前您正在添加MKPointAnnotation类型的注释,其中不包含viewForAnnotation方法所需的“年龄”信息(我假设这是它需要的) 。

    不要使用MKPointAnnotation,而是使Finding类(或self.finding对象的类型)实现MKAnnotation协议本身。您应该能够在SO上找到几个自定义注释类的示例。

    然后,在调用{{1}时,不是保留annotationFlag变量并创建MKPointAnnotation个对象,而是将Finding个对象本身(包含其“年龄”)直接添加到地图中}}

  2. addAnnotation中,在之后设置viewForAnnotation 创建/出列视图的if-else,并在pinColor之前。请务必根据传递给方法的return对象的age属性设置pinColor(这将是annotation类型对象)。例如:

    Finding