如何使自定义MKAnnotation可拖动

时间:2014-06-05 11:20:58

标签: ios objective-c mkmapview 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;
    }
}

注释在地图上显示正常,但由于某种原因它不可拖动:(

2 个答案:

答案 0 :(得分:8)

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

此外,自iOS 7起,您可能还需要实施mapView:annotationView:didChangeDragState:方法(请参阅Draggable Pin does not have a fixed position on mapiOS MapKit dragged annotations (MKAnnotationView) no longer pan with map)。

您可以自己显式实现setCoordinate:方法,也可以只声明一个可写coordinate属性(名称​​完全)并合成它(以及getter和setter方法)将自动为您实施)。

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


NavigationAnnotation课程中,要实施明确的手动解决方案以使用现有的theCoordinate媒体资源,只需 添加 setCoordinate:类实现的方法(保持现有的getter方法):

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


您可能还需要在实现地图视图委托的类中实现didChangeDragState:方法(具有viewForAnnotation方法的同一个),否则在拖动之后,注释视图将在原位上方悬停即使在底部平移或缩放时也要映射。由Chris K. in his answer

给出的方法的示例实现
- (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;
    }
}

答案 1 :(得分:1)

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

在我的注释视图中,我确实覆盖了- (void) setSelected:(BOOL)selected

不调用[super setSelected:selected]; 这样就防止了拖延...