如何使自定义MKAnnotation可拖动

我需要MKAnnotation与不同的引脚图像。
所以我创造了以下:

@interface NavigationAnnotation : NSObject <MKAnnotation> - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate; ... @interface NavigationAnnotation () @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *address; @property (nonatomic, assign) CLLocationCoordinate2D theCoordinate; @end @implementation NavigationAnnotation - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate { if ((self = [super init])) { if ([name isKindOfClass:[NSString class]]) { self.name = name; } else { self.name = @"Unknown charge"; } self.address = address; self.theCoordinate = coordinate; } return self; } - (NSString *)title { return _name; } - (NSString *)subtitle { return _address; } - (CLLocationCoordinate2D)coordinate { return _theCoordinate; } 

并像这样添加它:

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{ static NSString *identifier_OrderAnnotation = @"NavigateAnnotation"; if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; if ([annotation isKindOfClass:[NavigationAnnotation class]]) { MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier_OrderAnnotation]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier_OrderAnnotation]; annotationView.enabled = YES; annotationView.canShowCallout = YES; annotationView.draggable = YES; annotationView.image = [UIImage imageNamed:@"myimage.png"]; } else { annotationView.annotation = annotation; } return annotationView; } } 

注释显示在地图上,但不能从某种原因拖延:(

如前所述,为了使注释可拖动,必须实现setCoordinate:方法。

此外,自iOS 7以来,您可能还需要实现mapView:annotationView:didChangeDragState:方法(请参阅Draggable Pin在地图上没有固定位置,而iOS MapKit拖动的注释(MKAnnotationView)不再使用map平移 )。

你可以自己实现setCoordinate:方法,或者只声明一个可写的coordinate属性(就像这样命名)并合成它(并且getter和setter方法将自动为你实现)。

(请注意,如果使用预定义的MKPointAnnotation类,则不需要这样做,因为该类已经实现了可设置的coordinate属性。)

在您的NavigationAnnotation类中,要实现明确的手动解决scheme来处理现有的theCoordinate属性,只需 setCoordinate:方法添加到您的类实现中( 保留现有的getter方法):

 -(void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { self.theCoordinate = newCoordinate; } 

您可能还需要在实现地图视图委托的类(具有viewForAnnotation方法的同一个类)中实现didChangeDragState:方法,否则在拖动之后,注释视图将即使在平移时也会在地图上方原位hover或放大下方。 Chris K.在他的回答中给出的方法的一个示例实现:

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState { if (newState == MKAnnotationViewDragStateStarting) { annotationView.dragState = MKAnnotationViewDragStateDragging; } else if (newState == MKAnnotationViewDragStateEnding || newState == MKAnnotationViewDragStateCanceling) { annotationView.dragState = MKAnnotationViewDragStateNone; } } 

刚刚经历了这个问题…经过一番挣扎,原因不同(标题,坐标都没问题),所以在这里join可能的原因

在我的注释视图中,我没有覆盖- (void) setSelected:(BOOL)selected

不调用[super setSelected:selected]; 这阻止了发生拖动…