MKAnnotationView缓冲其input队列?

我想根据它们表示的相对时间在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; } 

也正在testing中是我邻居狗的好奇心。 每个针脚应该显示不同的颜色 <截图>

如果我NSLog annotationFlag控制在不同的点mapView:viewForAnnotation:似乎是忽略了annotationFlag中的值,并只使用最后设置的状态,导致我相信它只是在for循环完成后才动作,而不是跟随迭代。

所以问题是,为什么不立即调用[self.mapView addAnnotation:annotation]调用。 我把它放在循环中,在那里没有发生双倍的事情。

后期编辑:使用上面列表中所示的断点和login到控制台的组合,并注释掉年龄增长处理结果的42个元素(包括旧的准备废弃)的数组,被丢弃。

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

不能保证 viewForAnnotation将在addAnnotation之后被立即addAnnotation或者它只被调用一次。

注释可以添加到当前不可见的区域,或者用户可以平移或缩放导致注释回到视图中的地图。 地图视图只需要随时调用即可。

这是通过devise和简单的代表方法的工作方式。

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

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

  • 用不同的针脚颜色映射视图注释
  • 缩放后MKMapview注解dynamicpin图像发生变化
  • 地图注释显示所有点的所有相同图像/引脚
  • 为iOS等dynamic设置贴图颜色

为了您的问题具体,我build议如下:

  1. 现在你正在添加typesMKPointAnnotation注释,它不包含viewForAnnotation方法需要的“年龄”信息(我假设这是它所需要的)。

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

    然后,在调用addAnnotation时,而不是保留annotationFlagvariables并创buildMKPointAnnotation对象,直接将Finding对象(包含它们的“年龄”)添加到地图中。

  2. viewForAnnotation ,在创build/出队视图的if-else 之后return之前设置pinColor 。 请务必根据传递给方法(这将是一个Findingtypes对象)的annotation对象的age属性来设置pinColor 。 例如:

     - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation { if([annotation isKindOfClass:[MKUserLocation class]]) return nil; static NSString *identifier = @"myAnnotation"; MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (!annotationView) { annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; annotationView.animatesDrop = YES; annotationView.canShowCallout = NO; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeSystem]; }else { annotationView.annotation = annotation; } //update the pinColor in the view whether it's a new OR dequeued view... if ([annotation isKindOfClass:[Finding class]]) { Finding *f = (Finding *)annotation; if ([f.age isEqualToString:@"2"]) { annotationView.pinColor = MKPinAnnotationColorGreen; } else if ([f.age isEqualToString:@"1"]) { annotationView.pinColor = MKPinAnnotationColorPurple; } else { annotationView.pinColor = MKPinAnnotationColorRed; } } return annotationView; }