在Swift中检测CAShapeLayer上的点击?

我对iOS开发很新(所以请原谅我的无能 – 我到处寻找!),并且正在寻找一种方法来检测CAShapeLayer上的CAShapeLayer 。 到目前为止,我遇到了hitTesthitTest是最好的方法,如果是这样,它如何在Swift中使用,尤其是CAShapeLayer ? 另外,如果我有很多CAShapeLayers,我如何使用hitTest方法单独引用它们?

这就是我创建CAShapeLayer的方法:

  let newBounds = CGRect(x: 0, y: 0, width: 200, height: 200) let newShape = CAShapeLayer() newShape.bounds = newBounds newShape.position = view.center newShape.cornerRadius = newBounds.width / 2 newShape.path = UIBezierPath(ovalInRect: newShape.bounds).CGPath newShape.lineWidth = 42 newShape.strokeColor = UIColor(red: 222/255.0, green: 171/255.0, blue: 66/255.0, alpha: 1.0).CGColor newShape.fillColor = UIColor.clearColor().CGColor newShape.strokeStart = 0.2 newShape.strokeEnd = 0.4 view.layer.addSublayer(newShape) 

inheritance人是实现您想要实现目标的最佳方式:

 // First add the shapelayer let layer = CAShapeLayer() layer.anchorPoint = CGPointZero layer.path = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 100, height: 200)).CGPath layer.bounds = CGPathGetBoundingBox(layer.path) // IMPORTANT, without this hitTest wont work layer.fillColor = UIColor.redColor().CGColor self.view.layer.addSublayer(layer) // Check for touches override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { let point = touches.anyObject()!.locationInView(self.view) // Where you pressed if let layer = self.view.layer.hitTest(point) as? CAShapeLayer { // If you hit a layer and if its a Shapelayer if CGPathContainsPoint(layer.path, nil, point, false) { // Optional, if you are inside its content path println("Hit shapeLayer") // Do something } } } 

斯威夫特4

我的UIImageView有多个CAShapeLayer对象,这是我能够检测到它们的方法。

 override func touchesBegan(_ touches: Set, with event: UIEvent?) { let touch = touches.first guard let point = touch?.location(in: imageView) else { return } guard let sublayers = imageView.layer.sublayers as? [CAShapeLayer] else { return } for layer in sublayers{ if let path = layer.path, path.contains(point) { print(layer) } } } 

参考

我使用了Arbitur的代码,但我遇到了一些错误。 这是我没有错误的代码。 对于swift 3.2 / 4.0

 override func viewDidLoad() { super.viewDidLoad() let layer = CAShapeLayer() layer.anchorPoint = CGPoint.zero layer.path = UIBezierPath.init(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 200)).cgPath layer.bounds = (layer.path?.boundingBox)! // IMPORTANT, without this hitTest wont work layer.fillColor = UIColor.red.cgColor self.view.layer.addSublayer(layer) } // Check for touches override func touchesBegan(_ touches: Set, with event: UIEvent?) { let point = touches.first?.location(in: self.view) // Where you pressed if let layer = self.view.layer.hitTest(point!) as? CAShapeLayer { // If you hit a layer and if its a Shapelayer if (layer.path?.contains(point!))! { // Optional, if you are inside its content path print("Hit shapeLayer") // Do something } } } 

使用以下代码获取CAShapeLayer

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { CGPoint touchLocation = [touch locationInView:self.view]; for (id sublayer in self.view.layer.sublayers) { BOOL touchInLayer = NO; if ([sublayer isKindOfClass:[CAShapeLayer class]]) { CAShapeLayer *shapeLayer = sublayer; if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) { // Here your code for do any opration. touchInLayer = YES; } } else { CALayer *layer = sublayer; if (CGRectContainsPoint(layer.frame, touchLocation)) { // Touch is in this rectangular layer touchInLayer = YES; } } } } }