2016-05-08 3 views
2

я могу обнаружить прикосновение CAShapeLayer как это (touchesEnded):CAShapeLayer обнаружить прикосновение во время анимации Swift

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 во время анимации пути?

ответ

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() 
Смежные вопросы