gpt4 book ai didi

ios - MKAnnotationView 是否缓冲其输入队列?

转载 作者:行者123 更新时间:2023-11-29 12:43:42 30 4
gpt4 key购买 nike

我想根据它们代表的相对时间在 UIMapView 中显示不同颜色的图钉
但似乎 mapView:viewForAnnotation: 方法的作用与调用时间无关。

在我的代码示例中,我已经将文件中较早和较新的位置检索到 self.fileArray 。该数组包含称为 findings 的对象,该对象具有(除其他外) age 属性。最新的发现从年龄@“0”开始,每次重新加载数组时都准备好接受新发现他们的年龄分别增长到@“1”和@“2”,之后他们就被淘汰了。

一旦他们接受了新的 age 属性,他们就会被发送到 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 循环中,并且那里没有加倍发生。

后期编辑:如上面的 list 所示,使用断点和登录到控制台的组合,并注释掉年龄增加处理导致 42 个元素的数组(包括准备丢弃的旧元素),因此有 42 个引脚被丢弃。

当到达 mapView:viewForAnnotation 方法时,我必须再单步执行 42 次,在第 43 次时,所有图钉立即掉落。仔细观察它的相同颜色,这样我就可以验证最后使用的颜色不会覆盖任何较早的颜色。如果这样可以澄清问题。

最佳答案

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

注解可以添加到当前不可见的区域,或者用户可能平移或缩放 map 导致注解重新出现在 View 中。 map View 会根据需要随时或经常调用它。

这是设计使然,也就是委托(delegate)方法方法的工作原理。

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

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

对于您的具体问题,我建议如下:

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

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

    然后,不是保留 annotationFlag 变量并创建 MKPointAnnotation 对象,而是添加 Finding 对象本身(包含它们的“年龄”)调用 addAnnotation 时直接添加到 map 。

  2. viewForAnnotation 中,将 pinColor 设置在创建/出列 View 的 if-else 之后,紧接在 之前>返回。请务必根据传递到方法中的 annotation 对象(这将是一个 Finding 类型对象)的 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;
    }

关于ios - MKAnnotationView 是否缓冲其输入队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24215210/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com