是否可以移动MKAnnotation的坐标而无需在地图中添加和删除注释?
答案 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中记录的方法:
您可能会进一步简化此方法 - 在任何情况下都可能不需要内部视图对象。
答案 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];
你为什么不想这样做?