这是关于使用 MKMapKit 的 iPhone 应用程序:
我为可拖动注释创建了一个自定义 MKAnnotationView。我想创建一个自定义动画。我使用以下代码设置了自定义图钉图像,并且注释是可拖动的(两者均未在此处显示,它发生在 map View 中):
- (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");
}
}
一切正常,注释向上移动了一点,可以拖动,当我释放注释时, map View 收到“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]; }];
}
动画在一秒钟内按需要运行,并且注释是可拖动的。但是当我释放注释时, map View 没有通过委托(delegate)接收结局。我还认识到,当我使用“UIView animateWithDuration...”制作动画时,在开始拖动后,随着动画开始,注释的气球会立即打开。当我在没有动画的情况下设置新中心时,气球保持关闭状态,只有在通过释放注释完成拖动后才会打开。
我做错了什么?这是重写 setDragState 的正确方法吗?我真的必须调用 super 类吗?但是如果没有在父类(super class)中设置拖动状态,我的 map View 就没有意识到拖动状态的变化。
我想知道 MKPinAnnotationView 的原始实现,但因为它是一个内部类,所以我找不到 setDragState 方法的描述。
感谢帮助。干杯,
本
最佳答案
我让图钉拖动工作正常,但试图找出为什么当您不覆盖 setDragState 时发生的图钉动画 - 在我的实现中不再起作用。你的问题包含了我的答案..谢谢!
您的代码的部分问题是,一旦您重写了 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; }];
}
}
关于iphone - 子类化 MKAnnotationView 并重写 setDragState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3677166/