触摸 MKMapView 会导致引脚轻微移动
Touching MKMapView causes pins to move slightly
我使用此代码在用户触摸的位置添加了一个图钉:
func addPin(tap: UITapGestureRecognizer) {
if (tap.state == UIGestureRecognizerState.Ended) {
var coordinate = mapView.convertPoint(tap.locationInView(mapView), toCoordinateFromView: mapView)
let address = addressAnnotationLogic.createWithCoordinate(coordinate)
mapView.addAnnotation(address)
routeLogic.addAddressAnnotation(address, toRoute: currentRoute!)
// reverse geocode
let pinLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(pinLocation!, completionHandler: {
(placemarks, error) -> Void in
if error != nil {
println("Reverse geocoder failed with error " + error.localizedDescription)
}
if placemarks.count > 0 {
let topResult = placemarks[0] as? CLPlacemark
self.addressAnnotationLogic.updateAnnotation(address, withPlacemark: topResult!)
}
})
}
}
我的 addressAnnotationLogic 只是创建一个支持 NSManagedObjectModel 来保存它,而我的 routeLogic 只是将它添加到另一个 NSManagedObjectModel 的路由中。我的委托方法非常标准。
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is AddressAnnotation {
var annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "SimplePinIdentifier")
annotationView.enabled = true
annotationView.animatesDrop = true
annotationView.draggable = false
annotationView.pinColor = MKPinAnnotationColor.Red
annotationView.canShowCallout = true
return annotationView
}
return nil
}
添加我的第一个图钉后,如果我再次触摸屏幕,由于某种原因,最初的图钉移动了一点点,这看起来不对。更令人沮丧的是,后来我在点之间绘制了一条 MKPolyline,然后图钉会稍微移动,使多边形线看起来不正确。这是关于什么的?为什么图钉在添加到 MKMapView 后只移动了一点点?
您可能应该在 AddressAnnotation
class dynamic
.
中制作 coordinate
属性
class AddressAnnotation: NSObject, MKAnnotation {
var title = ""
// this works
dynamic var coordinate: CLLocationCoordinate2D
// this doesn't
// var coordinate: CLLocationCoordinate2D
init(_ coord:CLLocationCoordinate2D)
{
coordinate = coord
}
}
如果这不起作用,请post您的 AddressAnnotation
class 和 updateAnnotation
方法的代码。
这是我认为会发生的情况:
您的注释首先获取从您第一次点击的屏幕坐标转换而来的 coordinate
。
然后,在您的地理编码器调用的异步完成处理程序中,您的 updateAnnotation()
方法被调用。
我假设您将 AddressAnnotation
的 coordinate
更新为其中最近的地标的坐标。
不幸的是,更新发生时,地图视图可能已经在原始位置绘制了您的 Pin 图。
异步更新坐标时,地图视图不会注意到它。
只有当它重新绘制注释时(由下一次点击提示),它才会获取更新后的坐标(因此您会看到从第一次点击坐标到最近位置标记坐标的移动)。
现在,地图视图实际上正在尝试通知其注释坐标的更改,以便它可以在新坐标处自动重绘。
为此,它使用了一种称为 Key-Value-Observing 的技术。 "Normal" Swift 属性不支持,但是。让他们 dynamic
做到了。
我使用此代码在用户触摸的位置添加了一个图钉:
func addPin(tap: UITapGestureRecognizer) {
if (tap.state == UIGestureRecognizerState.Ended) {
var coordinate = mapView.convertPoint(tap.locationInView(mapView), toCoordinateFromView: mapView)
let address = addressAnnotationLogic.createWithCoordinate(coordinate)
mapView.addAnnotation(address)
routeLogic.addAddressAnnotation(address, toRoute: currentRoute!)
// reverse geocode
let pinLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(pinLocation!, completionHandler: {
(placemarks, error) -> Void in
if error != nil {
println("Reverse geocoder failed with error " + error.localizedDescription)
}
if placemarks.count > 0 {
let topResult = placemarks[0] as? CLPlacemark
self.addressAnnotationLogic.updateAnnotation(address, withPlacemark: topResult!)
}
})
}
}
我的 addressAnnotationLogic 只是创建一个支持 NSManagedObjectModel 来保存它,而我的 routeLogic 只是将它添加到另一个 NSManagedObjectModel 的路由中。我的委托方法非常标准。
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is AddressAnnotation {
var annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "SimplePinIdentifier")
annotationView.enabled = true
annotationView.animatesDrop = true
annotationView.draggable = false
annotationView.pinColor = MKPinAnnotationColor.Red
annotationView.canShowCallout = true
return annotationView
}
return nil
}
添加我的第一个图钉后,如果我再次触摸屏幕,由于某种原因,最初的图钉移动了一点点,这看起来不对。更令人沮丧的是,后来我在点之间绘制了一条 MKPolyline,然后图钉会稍微移动,使多边形线看起来不正确。这是关于什么的?为什么图钉在添加到 MKMapView 后只移动了一点点?
您可能应该在 AddressAnnotation
class dynamic
.
coordinate
属性
class AddressAnnotation: NSObject, MKAnnotation {
var title = ""
// this works
dynamic var coordinate: CLLocationCoordinate2D
// this doesn't
// var coordinate: CLLocationCoordinate2D
init(_ coord:CLLocationCoordinate2D)
{
coordinate = coord
}
}
如果这不起作用,请post您的 AddressAnnotation
class 和 updateAnnotation
方法的代码。
这是我认为会发生的情况:
您的注释首先获取从您第一次点击的屏幕坐标转换而来的 coordinate
。
然后,在您的地理编码器调用的异步完成处理程序中,您的 updateAnnotation()
方法被调用。
我假设您将 AddressAnnotation
的 coordinate
更新为其中最近的地标的坐标。
不幸的是,更新发生时,地图视图可能已经在原始位置绘制了您的 Pin 图。
异步更新坐标时,地图视图不会注意到它。 只有当它重新绘制注释时(由下一次点击提示),它才会获取更新后的坐标(因此您会看到从第一次点击坐标到最近位置标记坐标的移动)。
现在,地图视图实际上正在尝试通知其注释坐标的更改,以便它可以在新坐标处自动重绘。
为此,它使用了一种称为 Key-Value-Observing 的技术。 "Normal" Swift 属性不支持,但是。让他们 dynamic
做到了。