检测 mkoverlay 上的触摸

use*_*829 1 mapkit mkmapview ios swift

我正在根据方向绘制叠加层。我从路线a绘制到路线b,然后从路线b绘制到路线c。

我想检测是否在 mkoverlay 上的任何位置点击了叠加层。

我使用了这个例子Detecting Touchs on MKOverlay in iOS7 (MKOverlayRenderer)

并将其转换为 swift 。

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    if let touch = touches.first {
        if touch.tapCount == 1 {
            let touchLocation = touch.location(in: self)
            let locationCoordinate = self.convert(touchLocation, toCoordinateFrom: self)

            let mapPoint: MKMapPoint = MKMapPointForCoordinate(locationCoordinate)
            let mapPointAsCGP = CGPoint(x: CGFloat(mapPoint.x), y: CGFloat(mapPoint.y))
            for overlay: MKOverlay in self.overlays {
                if (overlay is MKPolygon) {
                    let polygon: MKPolygon? = (overlay as? MKPolygon)
                    let mpr: CGMutablePath = CGMutablePath()
                    let polygonPoints = polygon?.points
                    let polygonPointCount = Int((polygon?.pointCount)!)
                    for p in 0..<polygonPointCount {
                        let mp: MKMapPoint = polygonPoints.unsafelyUnwrapped()[polygonPointCount]
                        if p == 0 {
                            mpr.move(to: CGPoint(x: CGFloat(mp.x), y: CGFloat(mp.y)), transform: .identity)
                        }
                        else {
                            mpr.addLine(to: CGPoint(x: CGFloat(mp.x), y: CGFloat(mp.y)), transform: .identity)
                        }
                    }

                    if mpr.contains(mapPointAsCGP, using: .winding, transform: .identity) {
                        print("test")
                    }
                }
            }

        }
    }

    super.touchesEnded(touches, with: event)
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么他们有 if 语句

if (overlay is MKPolygon)  
Run Code Online (Sandbox Code Playgroud)

因为它永远不会被调用,因为它是一个 mkoverlay 数组。

Tri*_*ton 6

我发现这样做比依赖触摸事件方法要好得多。

对于您的问题:

if (overlay is MKPolygon)
Run Code Online (Sandbox Code Playgroud)

我们需要将覆盖层投射到多边形,以便我们可以访问点数组并重建路径。尽管在下面的方法中,您只需要访问点数组,前提是 renderer.path 为零。由于我使用的是地图上当前的叠加层,因此我确信该路径不为零。

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let tap = UITapGestureRecognizer(target: self, action: #selector(mapTapped(_:)))

    self.map.addGestureRecognizer(tap)
}

func mapTapped(_ gesture: UITapGestureRecognizer){

    let point = gesture.location(in: self.map)

    let coordinate = self.map.convert(point, toCoordinateFrom: nil)

    let mappoint = MKMapPointForCoordinate(coordinate)

    for overlay in self.map.overlays {

        if let polygon = overlay as? MKPolygon {

            guard let renderer = self.map.renderer(for: polygon) as? MKPolygonRenderer else { continue }

            let tapPoint = renderer.point(for: mappoint)

            if renderer.path.contains(tapPoint) {

                print("Tap was inside this polygon")

                break // If you have overlapping overlays then you'll need an array of overlays which the touch is in, so remove this line.
            }

            continue
        }

        if let circle = overlay as? MKCircle {

            let centerMP = MKMapPointForCoordinate(circle.coordinate)

            let distance = MKMetersBetweenMapPoints(mappoint, centerMP) // distance between the touch point and the center of the circle

            if distance <= circle.radius {

                print("Tap was inside this circle")

                break // If you have overlapping overlays then you'll need an array of overlays which the touch is in, so remove this line.
            }

            continue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)