简体   繁体   中英

iOS CALayer tap recognizer

I have a line like this: 在此处输入图片说明

Which is drawn on a CAShapeLayer using the following code:

class LineView: UIView {

    let rwPath = UIBezierPath()
    let rwLayer = CAShapeLayer()
    let rwColor = UIColor(red: 11/255.0, green: 86/255.0, blue: 14/255.0, alpha: 1.0)

    func setData() {
        rwPath.move(to: CGPoint(x: 50.0, y: 50.0))
        for i in 1...200 {
            rwPath.addLine(to: CGPoint(x: i + 50, y: i + 50))
        }

        setUpRWLayer()
        layer.addSublayer(rwLayer)
    }

    private func setUpRWLayer() {
        rwLayer.path = rwPath.cgPath
        rwLayer.fillColor = nil
        rwLayer.lineCap = .butt
        rwLayer.lineDashPattern = nil
        rwLayer.lineDashPhase = 0.0
        rwLayer.lineJoin = .miter
        rwLayer.lineWidth = 3.0
        rwLayer.miterLimit = 10.0
        rwLayer.strokeColor = rwColor.cgColor
    }
}

I've been trying for a while to detect a tap on that line. I've tried using UITapGestureRecognizer and overriding touchesBegin:withEvent func, but nothing seems to work so I've come to ask here.

Hit test code:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let point = touches.first?.location(in: self)

    if let hitLayer = self.layer.hitTest(point!) as? CAShapeLayer {
        if (hitLayer.path?.contains(point!))! {
            print("Touched")
        }
    }
}

You need to create outline for it as it will work accurately for click event on CAShape layer

Try this code and let me know if you face any issue

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch = touches.first

    guard let point = touch?.location(in: self.view) else { return }
    guard let sublayers = self.view.layer.sublayers else { return }
    var caShapelayers : [CAShapeLayer] = []
    for layer in sublayers {
        if layer is CAShapeLayer{
            caShapelayers.append(layer as! CAShapeLayer)
        }
    }

    for layer in caShapelayers {
        if let path = layer.path{
            let outline = path.copy(strokingWithWidth: 13, lineCap: .square, lineJoin: .round, miterLimit: 0)

            let iscontain = outline.contains(point)
            if iscontain  {
                //    print(layer)
                Singleton.sharedSingleton.showAlert(controller: self, message: "You want to delete this link?", title: "Are you sure?") { (buttonPressed) in
                    if (buttonPressed == "YES"){
                        layer.removeFromSuperlayer()
                    }
                }

            }
        }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM