防止MKMapView

时间:2016-01-17 05:41:25

标签: ios mapkit mapkitannotation

我的应用中有一种情况我要禁用注释取消选择(除了选择另一个时),所以当我点击注释视图的任何地方时,它应该保留当前选中的注释原样。如果我点击另一个注释视图,它应该选择那个注释视图并取消选择另一个注释视图。

我希望找到willDeselectAnnotationView中的MKMapViewDelegateisDeselectedMKAnnotationView的内容,但遗憾的是没有这样的内容。我还尝试在deselectAnnotation的自定义子类中覆盖MKMapView,但似乎触发的取消选择不会调用该函数。

是否可以在保留选择功能的同时禁用注释取消选择?谢谢!

3 个答案:

答案 0 :(得分:3)

我找到了办法!创建一个名为“allowSelectionChanges”的布尔值,我现在只需将其作为全局。然后使用MKMapView的子类,其中包含以下覆盖函数:

override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        return allowSelectionChanges
    } 

如果要阻止注释选择和取消选择,请将此变量切换为false。它不会影响用户在地图上移动的能力!

以下是一个示例,说明当您点击标注以与其进行交互时,如何停止取消选择该标注。把它放在你的MKAnnotationView子类中:

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
        let rect = self.bounds
        var isInside = CGRectContainsPoint(rect, point)
        if !isInside {
            for view in self.subviews {
                isInside = CGRectContainsPoint(view.frame, point)
                if isInside {
                    allowSelectionChanges = false
                    return true
                }
            }
            allowSelectionChanges = true
        }

        return false
    }

答案 1 :(得分:0)

好的......我自己也有这个问题,而@clinton的回答指出我正确的方向,我想出了一个不需要你的MKAnnotationView子类知道的解决方案mapView的自定义属性。

这是我为Swift 3编写的解决方案:

public class <#CustomMapViewClass#>: MKMapView {

    private var allowSelectionChanges: Bool = true

    public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return allowSelectionChanges
    }

    public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let pointInside = super.point(inside: point, with: event)
        if !pointInside {
            return pointInside
        }

        for annotation in annotations(in: visibleMapRect) where annotation is <#CustomAnnotationViewClass#> {
            guard let view = self.view(for: annotation as! MKAnnotation) else {
                continue
            }
            if view.frame.contains(point) {
                allowSelectionChanges = true
                return true
            }
        }
        allowSelectionChanges = false

        return pointInside
    }

}

答案 2 :(得分:0)

我的工作基于@clinton和@ mihai-fratu。他们两个都给出了很好的答案,因此您也应该对其进行投票。我要补充的是,如果点击的注释在群集中,或者被禁用,那么您仍然会发生取消选择的情况。这是我尝试修复的代码。

public class <#CustomMapViewClass#>: MKMapView {

    private var allowSelectionChanges: Bool = true

    public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return allowSelectionChanges
    }

    public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let pointInside = super.point(inside: point, with: event)
        if pointInside {
            // Go through all annotations in the visible map rect
            for annotation in annotations(in: visibleMapRect) where annotation is MKAnnotation {
                // get the view of each annotation
                if let view: MKAnnotationView = self.view(for: annotation as! MKAnnotation) {
                    // work with the cluster view if there is one
                    let rootView = view.cluster ?? view
                    // If the frame of this view contains the selected point, then we are an annotation tap. Allow the gesture...
                    if (rootView.frame.contains(point)) {
                        allowSelectionChanges = rootView.isEnabled  // But only if the view is enabled
                        return pointInside
                    }
                }
            }
            // If you did not tap in any valid annotation, disallow the gesture
            allowSelectionChanges = false
        }
        return pointInside
    }
}