iOS刷新地图视图上的注释

12

我有一个地图视图,在这个视图中注释的坐标会不断更新,但是当我使用 setCoordinate 方法时,注释并没有移动。我该如何刷新注释以反映它们的坐标?

- (void)updateUnits {

    PFQuery *query = [PFQuery queryWithClassName:@"devices"];
    [query whereKeyExists:@"location"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (!error) {

            for (PFObject *row in objects) {

                PFGeoPoint *geoPoint = [row objectForKey:@"location"];
                CLLocationCoordinate2D coord = { geoPoint.latitude, geoPoint.longitude };

                for (id<MKAnnotation> ann in mapView.annotations) {

                    if ([ann.title isEqualToString:[row objectForKey:@"deviceid"]]) {

                        [ann setCoordinate:coord];

                        NSLog(@"latitude is: %f" , coord.latitude);
                        NSLog(@"Is called");
                        break;
                    }
                    else {

                        //[self.mapView removeAnnotation:ann];
                    }
                }
            }
        }
        else {

        }
    }];
}

1
这可以通过更改注释对象中的坐标来实现。它不需要删除注释,然后将其添加到地图中才能使更改生效。 - Nakul Sudhakar
@NakulSudhakar 但它没有改变吗? - Manish
7个回答

18

更新(以反映解决方案):

如果您拥有自己的自定义注释并实现了setCoordinate和/或合成坐标,则可能会出现问题。

来源:http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html

先前的解决方案:

您可以简单地删除所有注释,然后重新添加它们。

[mapView removeAnnotations:[mapView.annotations]];

[mapView addAnnotations:(NSArray *)];

或者将它们删除,之后逐一重新添加:

for (id<MKAnnotation> annotation in mapView.annotations)
{
    [mapView removeAnnotation:annotation];
    // change coordinates etc
    [mapView addAnnotation:annotation]; 
}

1
当你可以改变它们的坐标时,这将更加密集。 - Jon Erickson
它们是自定义注释吗?如果是,你重载了坐标属性吗? - Rowan Freeman
是的,它是自定义的。您说的重载坐标属性是什么意思? - Jon Erickson
3
你是否实现了一个名为setCoordinate的方法或者在任何地方使用过@synthesize coordinate?虽然可能性不大,但这可能会导致问题。 - Rowan Freeman
实际上,如果你往上看,我使用id<MKAnnotation>作为ann指针的类。所以它不会是一个自定义注释,对吧?但当注释在另一个方法中首次添加时,它是一个自定义注释,在那里我声明了setCoordinate方法并合成了coordinate。 - Jon Erickson
显示剩余2条评论

10

将添加注释的操作分派到主线程,而不是在后台线程上尝试修改UI

dispatch_async(dispatch_get_main_queue()) {
    self.mapView.addAnnotation(annotation)
}

1
谢谢!这帮助我解决了我的问题,即除非我手动移动地图,否则MapView不会更新我的添加注释。 - Florian Uhlemann

9

Nathan的答案的Swift 3.0版本(感谢Nathan):

DispatchQueue.main.async {
    mapView.addAnnotation(annotation)
}

顺便提一下,Nathan的回答应该得到更多的赞。我其实需要帮助删除一个注释,在主队列中分派更新可以解决同样的问题。


1
这是答案,直到苹果有更好的解决方案! - Octavio Antonio Cedeño

0
尝试使用 [self.mapView removeAnnotations:self.mapView.annotations]
- (void)viewDidAppear:(BOOL)animated
{

[super viewDidAppear:animated];

[self.mapView removeAnnotations:self.mapView.annotations];

PFQuery *query = [PFQuery queryWithClassName:@"caches"];

[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error)
 {
     for (PFObject *comment in comments)
     {
         NSString *tit = comment[@"titulo"];
         NSString *lat = comment[@"latitud"];
         NSString *lon = comment[@"longitud"];

         float latFloat = [lat floatValue];
         float lonFloat = [lon floatValue];

         CLLocationCoordinate2D Pin;
         Pin.latitude = latFloat;
         Pin.longitude = lonFloat;
         MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc]init];
         annotationPoint.coordinate = Pin;
         annotationPoint.title = tit;

         [self.mapView addAnnotation:annotationPoint];

     }

 }];
}

0

移除所有现有的注释,重新添加新的或更新的注释列表将刷新地图视图。 首先我尝试了:

mapView.annotations.removeAll()

但是收到了错误:

"Value of type '(MKMapRect) -> Set<AnyHashable>' has no member 'removeAll'"

然而这个有效:

for annotation in mapView.annotations{
    mapView.removeAnnotation(annotation)
}
// .. code to add the new or updated annotation list

0
为了实现暗模式,我需要刷新注释的视图。 我还必须调用委托方法来重新创建注释的视图。
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    if (@available(iOS 13.0, *)) {
        if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
            for (id<MKAnnotation> annotation in self.mapView.annotations) {
                [self.mapView removeAnnotation:annotation];
                [self.mapView addAnnotation:annotation];
                [self mapView:self.mapView viewForAnnotation:annotation];
            }
        }
    }
}

-1

只需添加

mapView.reloadStyle(self)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接