触摸MKMapView会导致引脚略微移动

时间:2015-06-15 22:17:45

标签: ios swift mapkit core-location

我添加了一个用户触摸此代码的引脚:

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之后,为什么引脚会移动一点点?感谢。

1 个答案:

答案 0 :(得分:5)

您应该在coordinateAddressAnnotation中设置dynamic媒体资源。

class AddressAnnotation: NSObject, MKAnnotation {
    var title = ""

    // this works
    dynamic var coordinate: CLLocationCoordinate2D

    // this doesn't
    // var coordinate: CLLocationCoordinate2D

    init(_ coord:CLLocationCoordinate2D)
    {
        coordinate = coord
    }
}

如果这不起作用,请发布AddressAnnotation类和updateAnnotation方法的代码。

以下是我的想法:

您的注释首先获得从您第一次点击的屏幕坐标转换的coordinate

然后,在地理编码器调用的异步完成处理程序中,调用updateAnnotation()方法。

我假设您将coordinate的{​​{1}}更新为最近的地标的坐标。 不幸的是,当更新发生时,Map View可能已经在原始位置绘制了Pin。

当坐标异步更新时,Map View不会注意到它。 只有当它重新绘制注释(由下一个点击提示)时,它才会获取更新的坐标(因此您可以看到从第一个点击坐标移动到最近的位置标记的坐标)。

现在,地图视图实际上是在尝试通知其注释坐标的变化,以便它可以在新坐标处自动重绘。 为此,它使用了一种名为Key-Value-Observing的技术。 "正常"然而,Swift属性并不支持这一点。让它们成为AddressAnnotation