36

是否可以在不从地图中添加和删除注释的情况下移动 MKAnnotation 的坐标?

4

11 回答 11

20

在 Swift 4.0 和 IOS 11.0 中,我只是将动态属性添加到 MKAnnotation 类的子类的坐标属性中,它可以工作:如果更新了 MKAnnotation 对象的坐标值,则 MapView 上的所有注释都会更新它们的位置:

class CarAnnotation: NSObject, MKAnnotation {
    @objc dynamic var coordinate: CLLocationCoordinate2D
    //Add your custom code here
}
于 2018-03-15T09:30:02.647 回答
19

我找到了一个非常简单的方法。我想顺利更新我的玩家的位置,而不需要删除然后重新添加玩家注释。这适用于 iOS4 之前的应用程序,它的作用是移动图钉并将地图居中放置在图钉的新位置:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];

这是同样的事情,但使用了 iOS4 的推荐块功能:

[UIView animateWithDuration:0.5 animations:^{
    [player setCoordinate:aLoc.coordinate];
    [mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
于 2010-07-05T13:47:17.303 回答
7

It is indeed possible without removing and adding the annotation off-course.

You'll need to observe your MKAnnotation's coordinate and update the MKAnnotationView's position when it changes. Alternatively you can (and this is probably the more elegant way of doing it) derive your own MKAnnotation and MKAnnotationView and make them "movable".

See Moving-MKAnnotationView for a detailed example which also animates the position of the annotation.

于 2011-03-14T15:19:39.870 回答
4

只需使用 KVO:

[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];

如果您的 MKAnnotation 有一个 setCoordinate 方法,只需在其中包含这些行:

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
    [self willChangeValueForKey:@"coordinate"];
    coordinate = newCoordinate;
    [self didChangeValueForKey:@"coordinate"];
}
于 2012-03-13T18:30:09.313 回答
4

子类 MKPointAnnotation,它能够自动将地图上的注释视图更新到新坐标。

于 2014-04-26T19:17:19.750 回答
2

Don't know whether it's more generally possible, but it is if you have your own custom MKAnnotationView.

I was able to adapt the approach documented at http://spitzkoff.com/craig/?p=108 by Craig Spitzkoff:

  1. Give your custom MKAnnotationView a reference to your MKAnnotation object
  2. Add an updateCoordinates method to the MKAnnotation object and call it when you want to change location of the annotation
  3. Call regionChanged on the custom MKAnnotationView to let it know when to reposition itself (e.g. when MKAnnotation has updated coordinates)
  4. In drawRect on the internal view object owned by your custom MKAnnotationView you can reposition using the coordinates of the MKAnnotation (you're holding a reference to it).

You could likely simplify this approach further - you may not require an internal view object in all circumstances.

于 2010-02-15T03:45:54.437 回答
1

如果您保留对注释的引用,对坐标属性进行更改,然后再次将注释添加到地图,注释视图的位置将更新。您不需要移除注释(这会导致注释视图暂时消失)。然而,当注释坐标更新时,这不会给你一个很好的过渡。它也不会导致内存泄漏,也不会将多个相同的注释添加到地图中(如果您查看地图视图上的注释数量,当您重新添加注释时它保持不变)。

于 2011-02-16T13:58:08.190 回答
1

更新注解的坐标或其他一些属性后,只需调用以下 MKMapViewDelegate 方法来重绘您的注解:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;

例如:

myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];
于 2014-07-03T23:51:58.593 回答
1

大多数答案都是基于您的注释是通过 MKPlacemark 扩展进行的。但是任何其他只实现 MKAnnotation 协议的对象(即标记的自定义图像)呢?它没有 setCoordinate 方法。所以这里是基于代码的答案,由100grams提供

    MKAnnotationView *av = [self.mapView viewForAnnotation:user];
    //user is an object which implements <MKAnnotation>
    // You will probably get your MKAnnotationView in your own way
    if (av){
        // here user returns CLLocationCoordinate2D coordinate  
        MKMapPoint mapPoint = MKMapPointForCoordinate([user getLastLocation]); 
        // converting mapPoint to CGPoint 
        CGPoint newPos;
        CGFloat zoomFactor =  self.mapView.visibleMapRect.size.width / self.mapView.bounds.size.width;
        newPos.x = mapPoint.x/zoomFactor;
        newPos.y = mapPoint.y/zoomFactor;
        // animation for annotation's move
        static NSString *POSITION_KEY=@"positionAnimation";
    static NSString *PATH_ANIMATION_KEY=@"position";
    if (MKMapRectContainsPoint(self.mapView.visibleMapRect, mapPoint)) {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:PATH_ANIMATION_KEY];
        animation.fromValue = [NSValue valueWithCGPoint:av.center];
        animation.toValue = [NSValue valueWithCGPoint:newPos];  
        animation.duration = 0.3;
        animation.delegate = av;
        animation.fillMode = kCAFillModeForwards;
        [av.layer addAnimation:animation forKey:POSITION_KEY];
    }
        // moving view
        av.center = newPos;

所以你基本上需要得到相应的 MKAnnotationView ,这也可以通过所有注释的迭代来实现,它是新的位置。我为所有这些创建了一个数组持有者(NSMutableArray *mapAnotaions),所以现在我可以像这样迭代:

for (id annotation in mapAnnotaions) {call refresh method here for id}
于 2012-07-18T16:31:26.683 回答
0

看看我的MapKitDragAndDrop示例,它允许您在 iPhone OS 3 和 iOS 4 上更新 MKAnnotation 和移动 MKAnnotationView(将使用内置的拖动支持)。

于 2010-06-30T22:41:19.397 回答
-6

似乎不可能更改 MKAnnotation 对象的坐标,然后将更改通知 MKMapView。

但是,从地图中删除先前的注释,更改注释对象的坐标并将其添加回地图效果很好。

[theMapView removeAnnotation:myAnnotation]; 
[myAnnotation setLatitude:newLatitude];
[theMapView addAnnotation:myAnnotation];

你为什么不想这样做呢?

于 2010-02-13T11:53:46.590 回答