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

Posted

技术标签:

【中文标题】触摸 MKMapView 会导致引脚轻微移动【英文标题】:Touching MKMapView causes pins to move slightly 【发布时间】:2015-06-15 22:17:45 【问题描述】:

我在用户使用此代码触摸的地方添加了一个图钉:

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 后会移动一点点?

【问题讨论】:

你在模拟器和设备上都测试过吗? @Skoua 是的,我已经在设备上尝试过了,同样的事情也发生了。这似乎有点奇怪。 触摸移动多少重要吗?比如,在模拟器中,如果你只点一下而不移动,还会发生吗? @BradzTech 不,我只需触摸屏幕上的任何位置,图钉就会移动一点点。 @Crystal 感谢您提供赏金,您也可以接受答案吗? 【参考方案1】:

您可能应该在您的AddressAnnotationdynamic 中创建coordinate 属性。

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() 方法被调用。

我假设您将AddressAnnotationcoordinate 更新为那里最近的地标的坐标。 不幸的是,当更新发生时,地图视图可能已经在原始位置绘制了您的 Pin 图。

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

现在,地图视图实际上是在尝试通知其注释坐标的变化,以便它可以在新坐标处自动重绘。 为此,它使用了一种称为 Key-Value-Observing 的技术。但是,“普通” Swift 属性不支持这一点。让他们dynamic 确实如此。

【讨论】:

以上是关于触摸 MKMapView 会导致引脚轻微移动的主要内容,如果未能解决你的问题,请参考以下文章

使用 MKMapView 和可触摸的子视图创建视图

强制 MKMapView viewForAnnotation 更新

标注在 MKMapView - iPhone 的引脚后面弹出

MKMapView 平移导致父 UIScrollView 滚动

带光环的 iPhone MKMapView 引脚

IOS 11 - 当另一个引脚落后时,MKMapView引脚对话框无法点击