如何在不添加/删除地图的情况下移动MKAnnotation?

时间:2010-02-13 01:44:49

标签: iphone objective-c mapkit mkmapview

是否可以移动MKAnnotation的坐标而无需在地图中添加和删除注释?

11 个答案:

答案 0 :(得分:17)

我发现了一种非常简单的方法。我想平滑地更新我的玩家的位置而不删除然后重新添加玩家注释。这适用于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];
}];

答案 1 :(得分:8)

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

class CarAnnotation: NSObject, MKAnnotation {
    @objc dynamic var coordinate: CLLocationCoordinate2D
    //Add your custom code here
}

答案 2 :(得分:7)

确实可以在不删除和添加注释的情况下使用。

您需要观察MKAnnotation的坐标并更改MKAnnotationView的位置。或者你可以(这可能是更优雅的方式)派生你自己的MKAnnotation和MKAnnotationView并使它们“可移动”。

请参阅Moving-MKAnnotationView以获取详细示例,该示例还可以为注释的位置设置动画。

答案 3 :(得分:4)

只需使用KVO:

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

如果您的MKAnnotation具有setCoordinate方法,请在这里包含以下行:

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
    [self willChangeValueForKey:@"coordinate"];
    coordinate = newCoordinate;
    [self didChangeValueForKey:@"coordinate"];
}

答案 4 :(得分:4)

子类MKPointAnnotation,它可以自动将地图上的注释视图更新为新坐标。

答案 5 :(得分:2)

不知道它是否更普遍,但是如果你有自己的自定义MKAnnotationView。

我能够调整Craig Spitzkoff在http://spitzkoff.com/craig/?p=108中记录的方法:

  1. 为您的自定义MKAnnotationView提供对MKAnnotation对象的引用
  2. 添加updateCoordinates方法 到MKAnnotation对象并调用 当你想改变位置时 注释
  3. 在自定义上调用regionChanged MKAnnotationView让它知道什么时候 重新定位自己(例如何时 MKAnnotation已更新 坐标)
  4. 在drawRect上 您拥有的内部视图对象 您可以自定义MKAnnotationView 使用坐标重新定位 MKAnnotation(你拿着一个 参考它。)。
  5. 您可能会进一步简化此方法 - 在任何情况下都可能不需要内部视图对象。

答案 6 :(得分:1)

如果保留对注释的引用,请更改坐标属性,然后再次将注释添加到地图中,注释视图的位置将更新。您不需要删除注释(这将导致注释视图暂时消失)。但是,当注释坐标更新时,这不会给您带来很好的转换。它也不会导致内存泄漏,也不会在地图上添加相同注释的多个(如果您查看mapview上的注释数量,则在重新添加注释时它会保持不变)。

答案 7 :(得分: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 * mapAnnotaions)所以现在我可以迭代:

for (id annotation in mapAnnotaions) {call refresh method here for id}

答案 8 :(得分:1)

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

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

e.g:

myAnnotation.coordinate = CLLocationCoordinate2DMake([newLat doubleValue], [newLon doubleValue]);
[self mapView:self.mapView viewForAnnotation:myAnnotation];

答案 9 :(得分:0)

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

答案 10 :(得分:-6)

似乎无法更改MKAnnotation对象的坐标,然后通知MKMapView更改。

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

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

你为什么不想这样做?