1

我在我的应用程序中遇到一种情况,我想禁用注释取消选择(除了选择另一个),所以当我点击任何不是注释视图的地方时,它应该保持当前选定的注释不变。如果我点击另一个注释视图,它应该选择那个并取消选择另一个。

我希望找到类似于 a willDeselectAnnotationViewin theMKMapViewDelegate或 an isDeselectedinMKAnnotationView的东西,但不幸的是没有这样的东西。我还尝试deselectAnnotation在 的自定义子类中进行覆盖MKMapView,但似乎点击触发的取消选择不会调用该函数。

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

4

3 回答 3

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
    }
于 2016-02-23T02:59:02.950 回答
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
    }
}
于 2020-01-17T23:20:13.647 回答
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
    }

}
于 2017-05-10T18:53:09.920 回答