是否可以使用可以拖动或选择的点注释视图?

时间:2016-12-20 22:27:58

标签: ios mapkit drag mkannotationview

我有MKMapView,显示了一些MKPinAnnotationView个对象 我希望能够拖动注释视图,但我也希望能够选择它。

问题:

当我实现委托功能

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {…}  

当我触摸到注释视图时,此功能立即被称为。它显示警报,从而阻止注释视图的拖动。

当我没有实现委托功能时,我可以按预期拖动注释视图。

我认为以下应该是可能的:
- 触摸注释视图 - 拖动时,移动注释视图 - 否则,即从注释视图中当我触摸时,选择它。

我怎样才能做到这一点?

编辑:

我的图钉注释视图没有标注。相反,当它被选中时,它会显示UIAlertController,以便用户可以选择进一步的操作。如果是这样,mapView将变暗,则无法访问。

我想要实现的行为是:

如果我触摸针注释视图(手指向下),则不会发生任何事情。

如果我然后移动手指(仍然向下),则应拖动图钉注释视图。如果我然后抬起手指,则引脚注释视图将被选中。

但是,如果我没有模仿手指,只需抬起它,就会选择针注释视图 (并显示警报视图)。

我希望这能澄清情况。

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是自己处理拖动并利用长按手势来管理您想要的操作(例如何时显示警报)。

此解决方案围绕 Rob的详细答案here构建,并添加了一些额外的逻辑来处理您问题的细节(即wasMoved实例属性)。

private var startLocation = CGPoint(x: 0.0, y: 0.0)
private var wasMoved = false

func handleLongPress(_ sender: UILongPressGestureRecognizer) {
    let location = sender.location(in: mapView)

    switch sender.state {
    case .began:
        startLocation = location
    case .changed:
        wasMoved = true
        sender.view?.transform = CGAffineTransform(translationX: location.x - startLocation.x, y: location.y - startLocation.y)
    case .ended, .cancelled:
        if wasMoved {
            let annotationView = sender.view as! MKAnnotationView
            let annotation = annotationView.annotation as! MKPointAnnotation

            let translate = CGPoint(x: location.x - startLocation.x, y: location.y - startLocation.y)
            let originalLocation = mapView.convert(annotation.coordinate, toPointTo: mapView)
            let updatedLocation = CGPoint(x: originalLocation.x + translate.x, y: originalLocation.y + translate.y)

            annotationView.transform = CGAffineTransform.identity
            annotation.coordinate = mapView.convert(updatedLocation, toCoordinateFrom: mapView)
        } else {
            let alert = UIAlertController(title: "Alert", message: "Here is my alert!", preferredStyle: .alert)

            let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
            alert.addAction(ok)

            present(alert, animated: true, completion: nil)
        }
        wasMoved = false
    default:
        break
    }
}

您的mapView(_:viewFor:)委托方法如下:

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard let reusablePin = mapView.dequeueReusableAnnotationView(withIdentifier: "Pin") as? MKPinAnnotationView else {
            let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "Pin")

            // Add the long press gesture recognizer to the annotation view
            let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
            longPress.minimumPressDuration = 0
            pin.addGestureRecognizer(longPress)

            return pin
        }

        reusablePin.annotation = annotation
        return reusablePin
    }
}