子类化MKAnnotationView并覆盖setDragState

Ben*_*wak 9 iphone cocoa-touch mapkit ios4

这是关于使用MKMapKit的iPhone App:

我为可拖动的注释创建了一个自定义MKAnnotationView.我想创建一个自定义动画.我设置了一个自定义图钉图像,注释是可拖动的(这里没有显示,它发生在mapview中),代码如下:

- (void) movePinUpFinished {

     [super setDragState:MKAnnotationViewDragStateDragging];
     [self setDragState:MKAnnotationViewDragStateDragging];
}

- (void) setDragState:(MKAnnotationViewDragState) myState {
     if (myState == MKAnnotationViewDragStateStarting) {
          NSLog(@"starting");
          CGPoint endPoint = CGPointMake(self.center.x,self.center.y-20);
          self.center = endPoint;
          [self movePinUpFinished];
     }
     if (myState == MKAnnotationViewDragStateEnding) {
          NSLog(@"ending");
          [super setDragState:MKAnnotationViewDragStateEnding];
          [self setDragState:MKAnnotationViewDragStateNone];
          [super setDragState:MKAnnotationViewDragStateNone];
     }
     if (myState == MKAnnotationViewDragStateDragging) {
          NSLog(@"dragging");
     }
     if (myState == MKAnnotationViewDragStateCanceling) {
          NSLog(@"cancel");
     }
     if (myState == MKAnnotationViewDragStateNone) {
          NSLog(@"none");
     }
}
Run Code Online (Sandbox Code Playgroud)

一切正常,注释向上移动一点,可拖动,当我发布注释时,mapview会收到"dragstateending".

但现在我希望动画在一段时间内运行并将dragStateStarting更改为以下内容:

if (myState == MKAnnotationViewDragStateStarting) {
          NSLog(@"starting");
          CGPoint endPoint = CGPointMake(self.center.x,self.center.y-20);
          [UIView animateWithDuration:1.0
           animations:^{ self.center = endPoint; }
           completion:^(BOOL finished){ [self movePinUpFinished]; }];
     }
Run Code Online (Sandbox Code Playgroud)

动画在一秒钟内按需运行,注释可拖动.但是当我发布注释时,mapview没有通过委托接收结尾.我还认识到,当我使用"UIView animateWithDuration ..."进行动画时,在开始拖动之后,当动画开始时,注释的气球就会打开.当我在没有动画的情况下设置新中心时,气球会保持关闭状态,并且只有在通过释放注释完成拖动后才会打开.

我究竟做错了什么?这是覆盖setDragState的正确方法吗?我真的要打电话给超级班吗?但是如果没有在超类中设置dragstate我的mapview没有意识到dragstate的变化.

我想知道MKPinAnnotationView的原始实现,但因为它是一个内部类,我找不到setDragState方法的描述.

谢谢你的帮助.干杯,

小智 23

我有pin拖动工作,但试图找出为什么当你不覆盖setDragState时发生的引脚annimations - 不再在我的实现中工作.你的问题包含我的答案..谢谢!

您的代码的部分问题在于,一旦覆盖了setDragState函数,根据xcode文档,您负责根据新状态更新dragState变量.我也会担心您的代码调用自身( setDragState调用[self setDragState]).

这是我最终得到的代码(在你的帮助下),它可以完成所有的提升,拖动和掉落.希望这对你也有帮助!

- (void)setDragState:(MKAnnotationViewDragState)newDragState animated:(BOOL)animated
{
    if (newDragState == MKAnnotationViewDragStateStarting)
    {
        // lift the pin and set the state to dragging

        CGPoint endPoint = CGPointMake(self.center.x,self.center.y-20);
        [UIView animateWithDuration:0.2
                         animations:^{ self.center = endPoint; }
                         completion:^(BOOL finished)
                             { self.dragState = MKAnnotationViewDragStateDragging; }];
    }
    else if (newDragState == MKAnnotationViewDragStateEnding)
    {
        // save the new location, drop the pin, and set state to none

        /* my app specific code to save the new position
        objectObservations[ACTIVE].latitude = pinAnnotation.coordinate.latitude;
        objectObservations[ACTIVE].longitude = pinAnnotation.coordinate.longitude;
        posChanged = TRUE;
        */

        CGPoint endPoint = CGPointMake(self.center.x,self.center.y+20);
        [UIView animateWithDuration:0.2
                         animations:^{ self.center = endPoint; }
                         completion:^(BOOL finished)
                             { self.dragState = MKAnnotationViewDragStateNone; }];
    }
    else if (newDragState == MKAnnotationViewDragStateCanceling)
    {
        // drop the pin and set the state to none

        CGPoint endPoint = CGPointMake(self.center.x,self.center.y+20);
        [UIView animateWithDuration:0.2
                         animations:^{ self.center = endPoint; }
                         completion:^(BOOL finished)
                             { self.dragState = MKAnnotationViewDragStateNone; }];
    }
}
Run Code Online (Sandbox Code Playgroud)