CAShapeLayer在动画Swift期间检测触摸

时间:2016-05-08 17:14:28

标签: ios swift core-animation cashapelayer cabasicanimation

我可以检测到这样的触摸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")
    }
}

我可以像这样动画CAShapeLayer的路径:

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)

但是当动画发生时,在CAShapeLayer上没有检测到触摸。在动画路径时是否可以检测CAShapeLayer上的触摸?

1 个答案:

答案 0 :(得分:6)

您可以访问图层presentationLayer以执行此操作。这将为您提供“飞行中”的粗略近似值。动画时给定图层的值。例如:

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")
    }
}

此外,作为旁注,如果您不使用动画代表,则使用removedOnCompletion = false通常会被视为不良做法。您应该只更新图层的模型值以表示其新状态,而不是让动画保持不变。您可以通过CATransaction执行此操作,以确保不会生成隐式动画。例如:

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