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()