我想根据它们表示的相对时间在UIMapView中显示不同的颜色图钉
但似乎mapView:viewForAnnotation:方法只是独立于调用时间而已。

在我的代码示例中,我已经从文件中将较早和较新的位置检索到self.fileArray。
该数组包含称为发现的对象,这些对象具有(以及其他)年龄属性。
最新发现的起始年龄为“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;
}

同样在考验中的是我的邻居对狗的好奇心。每次尝试时,图钉应显示不同的颜色


如果我在各个点进行控制台的NSLog注解标记,则mapView:viewForAnnotation:似乎是
忽略注释注解中的值,仅使用最后设置的状态,使我相信它仅在以下情况下起作用
for循环已完全完成,并且没有后续迭代。

所以问题是,为什么[self.mapView addAnnotation:annotation]调用不立即起作用。香港专业教育学院把它放在for循环中,并且那里没有发生任何加倍。

后期编辑:
使用上面的清单中所示的断点和日志到控制台的组合,并注释掉年龄增长处理,结果导致了42个元素的数组(包括准备丢弃的旧元素),因此有42个引脚被丢弃。

当到达mapView:viewForAnnotation方法时,我必须再次执行42次,并在第43次将所有引脚一次掉线。仔细观察其相同的颜色,这样我就可以验证使用的最后一种颜色不会覆盖任何以前的颜色。如果这样可以解决问题。

最佳答案

不能保证在viewForAnnotation之后立即调用addAnnotation或仅将其调用一次。

可以将注释添加到当前不可见的区域中,或者用户可能会平移或缩放 map ,从而使注释重新显示。 map 视图将根据需要随时随地调用它。

这是设计使然,只是委托方法的工作原理。

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

有关可以更详细解释此问题的其他答案,请参见:

  • Map view annotations with different pin colors
  • MKMapview annotation dynamic pin image changes after zooming
  • Map annotation display all the same image/pins for all points
  • Setting Map Pin colour dynamically for iOS

  • 具体针对您的问题,我建议以下几点:
  • 现在,您要添加MKPointAnnotation类型的注释,其中不包含viewForAnnotation方法所需的“年龄”信息(我假设这就是它的需要)。

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

    然后,代替保留annotationFlag变量并创建MKPointAnnotation对象,而是在调用Finding时将addAnnotation对象本身(包含其“年龄”)直接添加到 map 中。
  • viewForAnnotation中,将pinColor设置在创建/出队视图的if-else之后,并在return之前。确保根据传递到方法中的pinColor对象的age属性设置annotation(它将是Finding类型的对象)。例如:
    - (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/

    10-10 21:13