2017-05-30 29 views
0

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

Touch将忽略转换并检测错误位置的图层。

重现步骤:

创建其中I覆盖拉伸的自定义视图:方法来创建的若干形状上的层的路径。

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

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

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

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

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

IIRC从我的数学课,你有你的应用层的倒仿射变换你的'touchLocation'在测试之前。 – Cyrille

+0

是的你是对的。它倒过来了。非常感谢。 –

+0

请您以回答的形式发帖。这个技巧:let touchLocation = touch.location(in:self).applying(affineTransform.inverted()) –

回答

0

您必须应用测试之前,您层的倒仿射变换你的touchLocation

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