gpt4 book ai didi

iOS MapKit 拖动注释(MKAnnotationView)不再随 map 平移

转载 作者:可可西里 更新时间:2023-11-01 06:18:56 25 4
gpt4 key购买 nike

我正在学习如何在我初出茅庐的 iOS 应用程序中使用 MapKit。我将我的一些模型实体用作注释(将 <MKAnnotation> 协议(protocol)添加到它们的头文件中)。我还创建自定义 MKAnnotationViews 并设置 draggable属性(property)YES .

我的模型对象有一个 location属性,这是一个 CLLocation* .符合 <MKAnnotation>协议(protocol),我向该对象添加了以下内容:

- (CLLocationCoordinate2D) coordinate {
return self.location.coordinate;
}

- (void) setCoordinate:(CLLocationCoordinate2D)newCoordinate {
CLLocation* newLocation = [[CLLocation alloc]
initWithCoordinate: newCoordinate
altitude: self.location.altitude
horizontalAccuracy: self.location.horizontalAccuracy
verticalAccuracy: self.location.verticalAccuracy
timestamp: nil];
self.location = newLocation;
}

- (NSString*) title {
return self.name;
}

- (NSString*) subtitle {
return self.serialID;
}

所以,我有 4 个必需的方法。而且它们非常简单。当我在 MKAnnotationView 上阅读苹果文档时和 @draggable属性,它表示如下:

Setting this property to YES makes an annotation draggable by the user. If YES, the associated annotation object must also implement the setCoordinate: method. The default value of this property is NO.

在其他地方,MKAnnotation文档说:

Your implementation of this property must be key-value observing (KVO) compliant. For more information on how to implement support for KVO, see Key-Value Observing Programming Guide.

我已经阅读了那个(简短的)文档,但我完全不清楚我应该做什么来完成它,以便 coordinate ,这是我从我的 location 中得出的属性本身就是一个适当的属性。

但我有理由相信它无法正常工作。当我拖动图钉时,它会移动,但当我平移 map 时它不再重新定位。

更新

所以我尝试使用常用的 MKPinAnnotationView。为此,我简单地注释掉了我代表的 mapView:viewForAnnotation:。方法。我发现这些默认情况下不可拖动。我添加了 mapView:didAddAnnotationViews:给我的代表设置 draggable添加到 YES 的 View 的属性.

这样配置后,Pin View (正如下面 John Estropia 所暗示的那样)似乎工作正常。我决定使用 mapView:annotationView:didChangeDragState:fromOldState: delegate hook 以更仔细地了解正在发生的事情:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {
NSArray* states = @[@"None", @"Starting", @"Dragging", @"Cancelling", @"Ending"];
NSLog(@"dragStateChangeFrom: %@ to: %@", states[oldState], states[newState]);
}

对于备用引脚,您将看到如下所示的日志输出:

2014-02-05 09:07:45.924 myValve[1781:60b] dragStateChangeFrom: None to: Starting
2014-02-05 09:07:46.249 myValve[1781:60b] dragStateChangeFrom: Starting to: Dragging
2014-02-05 09:07:47.601 myValve[1781:60b] dragStateChangeFrom: Dragging to: Ending
2014-02-05 09:07:48.006 myValve[1781:60b] dragStateChangeFrom: Ending to: None

这看起来很合乎逻辑。但是如果你切换到配置的MKAnnotationView ,您将看到的输出如下所示:

2014-02-05 09:09:41.389 myValve[1791:60b] dragStateChangeFrom: None to: Starting
2014-02-05 09:09:45.451 myValve[1791:60b] dragStateChangeFrom: Starting to: Ending

它错过了两个过渡,从开始到拖动,从结束到无。

所以我开始怀疑我是否需要对属性做一些不同的事情。但我仍然对为什么这行不通感到沮丧。

更新 2

我创建了自己的 Annotation对象站在我的模型对象之间,它可能有一个属性 coordinate属性(property)。行为保持不变。这似乎与 MKAnnotationView 有关.

最佳答案

有很多关于如何使用委托(delegate)方法 mapView:viewForAnnotation: 的示例,这些示例展示了如何设置 MKAnnotationView。但不那么明显的是,仅仅因为您将 MKAnnotationView 实例的 draggable 属性设置为 YES,您仍然需要编写一些代码帮助它过渡一些州。 MapKit 会负责将实例的 dragState 移动到 MKAnnotationViewDragStateStartingMKAnnotationViewDragStateEnding,但它不会执行其他转换。您在关于子类化 MKAnnotationView 的文档注释中看到了这方面的提示,并且需要覆盖 `setDragState:animated:'

When the drag state changes to MKAnnotationViewDragStateStarting, set the state to MKAnnotationViewDragStateDragging. If you perform an animation to indicate the beginning of a drag, and the animated parameter is YES, perform that animation before changing the state.

When the state changes to either MKAnnotationViewDragStateCanceling or MKAnnotationViewDragStateEnding, set the state to MKAnnotationViewDragStateNone. If you perform an animation at the end of a drag, and the animated parameter is YES, you should perform that animation before changing the state.

在这种情况下,我没有子类化,但似乎 MKAnnotationView 仍然难以自行进行转换。所以你必须实现委托(delegate)的 mapView:annotationView:didChangeDragState:fromOldState: 方法。例如

- (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;}
}
}

这允许事情适本地完成,这样当您在拖动注释后平移 map 时,注释会随着平移移动。

关于iOS MapKit 拖动注释(MKAnnotationView)不再随 map 平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21567082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com