检测变形的shapelayer上的触摸

时间:2017-05-30 07:02:48

标签: ios swift cashapelayer

我在检测已转换的形状图层上的触摸时遇到问题。

触摸忽略转换并检测错误位置的图层。

重现的步骤:

我创建了一个自定义视图,我在其中覆盖了draw:方法,以在形状图层上创建多个路径。

形状图层在视图中转换到新的位置和大小。

当我尝试检测是否触摸了形状图层时,检测位置错误。

查看下面的屏幕截图,红色形状图层是视图中绘制的图层。

轮廓形状是原始未转换的形状(未在视图中绘制)。

enter image description here

当我触摸红色形状图层时,未检测到任何内容。

如果触摸原始形状没有任何变换的屏幕,则会检测到形状图层!

这意味着正在屏幕的空白部分检测到形状图层。

要重现的代码:

@IBDesignable
class CustomView: UIView {

    let bezierPaths: [UIBezierPath] = MyShapes.headShape()

    override func draw(_ rect: CGRect) {

        //draw each bezierPath onto its own shape layer
        for bezierPath in bezierPaths {

            let shapeLayer = CAShapeLayer()

            shapeLayer.fillColor = UIColor.red.cgColor
            shapeLayer.strokeColor = UIColor.red.cgColor
            shapeLayer.lineWidth = 1
            shapeLayer.path = bezierPath.cgPath

            //transform shape to new size and position in view
            let scale = CGAffineTransform(scaleX: 1.5, y: 1.5)
            let transform = CGAffineTransform(translationX: 100, y: 100)
            let affineTransform = scale.concatenating(transform)
            shapeLayer.setAffineTransform(affineTransform)

            //add the shape layer to the view
            self.layer.addSublayer(shapeLayer)

        }

    }

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

        for touch in touches {
            let touchLocation = touch.location(in: self)

            for sublayer in self.layer.sublayers! {

                if let shapeLayer = sublayer as? CAShapeLayer {
                    if shapeLayer.path!.contains(touchLocation) {

                        print("touched the shape layer")

                    }
                }

            }

        }        

    }

}


class MyShapes {

    static func headShape() -> [UIBezierPath] {

        var paths = [UIBezierPath]()

        let frame: CGRect = CGRect(x: 0, y: 0, width: 285, height: 508)

        //create shape and add to array
        let head_FrontPath = UIBezierPath()
        head_FrontPath.move(to: CGPoint(x: frame.minX + 164.47, y: frame.minY + 34.31))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 165.1, y: frame.minY + 28.52), controlPoint1: CGPoint(x: frame.minX + 164.76, y: frame.minY + 32.42), controlPoint2: CGPoint(x: frame.minX + 165, y: frame.minY + 30.44))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 161.97, y: frame.minY + 12.86), controlPoint1: CGPoint(x: frame.minX + 165.42, y: frame.minY + 22.25), controlPoint2: CGPoint(x: frame.minX + 163.22, y: frame.minY + 15.36))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 149.75, y: frame.minY + 0.95), controlPoint1: CGPoint(x: frame.minX + 160.72, y: frame.minY + 10.35), controlPoint2: CGPoint(x: frame.minX + 155.7, y: frame.minY + 3.15))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.5, y: frame.minY + 0.1), controlPoint1: CGPoint(x: frame.minX + 146.73, y: frame.minY - 0.16), controlPoint2: CGPoint(x: frame.minX + 144.37, y: frame.minY + 0.1))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 135.25, y: frame.minY + 0.95), controlPoint1: CGPoint(x: frame.minX + 140.63, y: frame.minY + 0.1), controlPoint2: CGPoint(x: frame.minX + 138.28, y: frame.minY - 0.16))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 123.03, y: frame.minY + 12.86), controlPoint1: CGPoint(x: frame.minX + 129.3, y: frame.minY + 3.15), controlPoint2: CGPoint(x: frame.minX + 124.29, y: frame.minY + 10.35))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 119.9, y: frame.minY + 28.52), controlPoint1: CGPoint(x: frame.minX + 121.78, y: frame.minY + 15.36), controlPoint2: CGPoint(x: frame.minX + 119.59, y: frame.minY + 22.25))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 120.6, y: frame.minY + 34.76), controlPoint1: CGPoint(x: frame.minX + 120, y: frame.minY + 30.59), controlPoint2: CGPoint(x: frame.minX + 120.28, y: frame.minY + 32.73))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 117.33, y: frame.minY + 37.38), controlPoint1: CGPoint(x: frame.minX + 119.21, y: frame.minY + 35.05), controlPoint2: CGPoint(x: frame.minX + 116.96, y: frame.minY + 36.32))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 122.02, y: frame.minY + 48.93), controlPoint1: CGPoint(x: frame.minX + 117.83, y: frame.minY + 38.83), controlPoint2: CGPoint(x: frame.minX + 120.95, y: frame.minY + 50.57))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 122.31, y: frame.minY + 47.94), controlPoint1: CGPoint(x: frame.minX + 122.15, y: frame.minY + 48.73), controlPoint2: CGPoint(x: frame.minX + 122.25, y: frame.minY + 48.39))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 124.28, y: frame.minY + 58.91), controlPoint1: CGPoint(x: frame.minX + 122.66, y: frame.minY + 51.97), controlPoint2: CGPoint(x: frame.minX + 123.39, y: frame.minY + 57.57))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 134.31, y: frame.minY + 64.55), controlPoint1: CGPoint(x: frame.minX + 125.54, y: frame.minY + 60.79), controlPoint2: CGPoint(x: frame.minX + 132.74, y: frame.minY + 64.24))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.23, y: frame.minY + 66.38), controlPoint1: CGPoint(x: frame.minX + 135.73, y: frame.minY + 64.83), controlPoint2: CGPoint(x: frame.minX + 140.24, y: frame.minY + 66.14))
        head_FrontPath.addLine(to: CGPoint(x: frame.minX + 142.23, y: frame.minY + 66.43))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.5, y: frame.minY + 66.4), controlPoint1: CGPoint(x: frame.minX + 142.3, y: frame.minY + 66.43), controlPoint2: CGPoint(x: frame.minX + 142.41, y: frame.minY + 66.41))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.77, y: frame.minY + 66.43), controlPoint1: CGPoint(x: frame.minX + 142.58, y: frame.minY + 66.41), controlPoint2: CGPoint(x: frame.minX + 142.7, y: frame.minY + 66.43))
        head_FrontPath.addLine(to: CGPoint(x: frame.minX + 142.77, y: frame.minY + 66.38))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 150.69, y: frame.minY + 64.55), controlPoint1: CGPoint(x: frame.minX + 144.75, y: frame.minY + 66.14), controlPoint2: CGPoint(x: frame.minX + 149.27, y: frame.minY + 64.83))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 160.71, y: frame.minY + 58.91), controlPoint1: CGPoint(x: frame.minX + 152.26, y: frame.minY + 64.23), controlPoint2: CGPoint(x: frame.minX + 159.46, y: frame.minY + 60.79))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 162.71, y: frame.minY + 47.63), controlPoint1: CGPoint(x: frame.minX + 161.63, y: frame.minY + 57.54), controlPoint2: CGPoint(x: frame.minX + 162.37, y: frame.minY + 51.68))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 162.97, y: frame.minY + 48.46), controlPoint1: CGPoint(x: frame.minX + 162.77, y: frame.minY + 48), controlPoint2: CGPoint(x: frame.minX + 162.86, y: frame.minY + 48.29))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 167.67, y: frame.minY + 36.91), controlPoint1: CGPoint(x: frame.minX + 164.05, y: frame.minY + 50.1), controlPoint2: CGPoint(x: frame.minX + 167.16, y: frame.minY + 38.36))
        head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 164.47, y: frame.minY + 34.31), controlPoint1: CGPoint(x: frame.minX + 168.03, y: frame.minY + 35.87), controlPoint2: CGPoint(x: frame.minX + 165.87, y: frame.minY + 34.63))
        head_FrontPath.close()
        paths.append(head_FrontPath)

        //create a number of other shapes
        //...
        //...
        //...

        //return array of shapes
        return paths
    }

}

如何使用触摸在屏幕上的正确位置检测转换后的形状?

1 个答案:

答案 0 :(得分:0)

在测试之前,您必须将图层的反转仿射变换应用到touchLocation

let touchLocation = touch.location(in: self).applying(affineTransform.inverted())