web-dev-qa-db-ja.com

マップに追加/削除せずにMKAnnotationを移動するにはどうすればよいですか?

マップに注釈を追加したり、マップから注釈を削除したりせずに、MKAnnotationの座標を移動することは可能ですか?

36
DevDevDev

とても簡単な方法を見つけました。プレーヤーの注釈を削除してから再度追加することなく、プレーヤーの位置をスムーズに更新したかったのです。これは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];
}];
19
spstanley

Swift 4.0およびIOS 11.0では、MKAnnotationクラスの子クラスの座標プロパティに動的属性を追加するだけで機能します。MapViewのすべてのアノテーションはMKAnnotationオブジェクトの座標値が更新された場合の場所:

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

コース外で注釈を削除および追加しなくても、実際に可能です。

MKAnnotationの座標を観察し、変更されたときにMKAnnotationViewの位置を更新する必要があります。あるいは、独自のMKAnnotationとMKAnnotationViewを導出して、それらを「移動可能」にすることもできます(これはおそらくよりエレガントな方法です)。

注釈の位置もアニメーション化する詳細な例については、 Moving-MKAnnotationView を参照してください。

7
100grams

KVOを使用するだけです。

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

MKAnnotationにsetCoordinateメソッドがある場合は、次の行をその場に含めてください。

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

MKPointAnnotationをサブクラス化し、マップ上の注釈ビューを新しい座標に自動的に更新する機能があります。

4
malhal

それがより一般的に可能かどうかはわかりませんが、独自のカスタムMKAnnotationViewがある場合はそうです。

http://spitzkoff.com/craig/?p=108 でCraig Spitzkoffによって文書化されたアプローチを適応させることができました:

  1. カスタムMKAnnotationViewにMKAnnotationオブジェクトへの参照を与える
  2. UpdateCoordinatesメソッドをMKAnnotationオブジェクトに追加し、アノテーションの場所を変更するときに呼び出します
  3. カスタムMKAnnotationViewでregionChangedを呼び出して、それ自体をいつ再配置するかを通知します(たとえば、MKAnnotationが座標を更新したとき)
  4. カスタムMKAnnotationViewが所有する内部ビューオブジェクトのdrawRectで、MKAnnotationの座標を使用して再配置できます(MKAnnotationへの参照を保持しています)。

このアプローチをさらに単純化できる可能性があります。すべての状況で内部ビューオブジェクトが必要なわけではありません。

2
StephenT

注釈の座標またはその他のプロパティを更新した後、次のMKMapViewDelegateメソッドを呼び出して注釈を再描画します。

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

例えば。:

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

ほとんどの回答は、注釈が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}
1
Stan

注釈への参照を保持し、座標プロパティを変更してから、注釈をマップに再度追加すると、注釈ビューの場所が更新されます。注釈を削除する必要はありません(注釈ビューが一時的に消えます)。ただし、これでは、注釈座標が更新されたときの適切な遷移は得られません。また、メモリリークが発生したり、マップに同じ注釈が複数追加されたりすることもありません(マップビューで注釈の数を確認すると、注釈を再度追加しても一定のままです)。

1
Willster

私の MapKitDragAndDrop サンプルを見てください。これにより、iPhone OS3とiOS4の両方でMKAnnotationを更新し、MKAnnotationViewを移動できます(組み込みのドラッグサポートを使用します)。

0
digdog