CAShapeLayer在animationSwift中检测触摸

我可以检测到这样一个CAShapeLayer触摸(touchesEnded):

let touchLocation : CGPoint = (touch as! UITouch).locationInView(self.view) for shape in shapes{ if CGPathContainsPoint(shape.path, nil, touchLocation, false){ print("Layer touch") } } 

而且我可以像这样animation化一个CAShapeLayer的path:

 let newShapePath = UIBezierPath(arcCenter: toPoint, radius: 20, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true).CGPath // animate the `path` let animation = CABasicAnimation(keyPath: "path") animation.toValue = newShapePath animation.duration = CFTimeInterval(duration) animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) animation.fillMode = kCAFillModeBoth animation.removedOnCompletion = false shape.addAnimation(animation, forKey: animation.keyPath) 

但是在animation发生时,CAShapeLayer上没有检测到触摸。 animationpath时是否可以检测CAShapeLayer上的一个触摸?

您可以访问该图层的presentationLayer为了做到这一点。 这将为您提供一个粗略的近似值,在给定图层的“飞行中”值的同时animation。 例如:

 for shape in shapes { // gets the layer's presentation layer if it exists – else fallback on the model layer let presentationLayer = shape.presentationLayer() as? CAShapeLayer ?? shape if CGPathContainsPoint(presentationLayer.path, nil, touchLocation, false){ print("Layer touch") } } 

此外,作为一个方面说明,如果您不使用animation委托,则一般认为使用removedOnCompletion = false是不好的做法。 不要让animation留下来,你应该更新图层的模型值来表示它的新状态。 您可以通过CATransaction执行此CATransaction以确保不生成隐式animation。 例如:

 let animation = CABasicAnimation(keyPath: "path") animation.fromValue = shape.path animation.toValue = newShapePath animation.duration = CFTimeInterval(duration) animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) shape.addAnimation(animation, forKey: animation.keyPath) // update the layer's model values CATransaction.begin() CATransaction.setDisableActions(true) shape.path = newShapePath CATransaction.commit()