2017-08-25 59 views
0

下面的问题是给缩放动画的持续时间会覆盖旋转动画。同时动画不同持续时间的图层变换的旋转和缩放比例

是否有其他方法可以同时为CALayer的缩放和旋转设置不同的持续时间?

// Animate arrowhead rotation 
    CATransaction.begin() 
    CATransaction.setAnimationDuration(0.2) 
    CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)) 
    let arrowAngle = atan2(path.currentPoint.y - previousPoint.y, 
          path.currentPoint.x - previousPoint.x) + (.pi * 0.5) 
    let rotationZ = CATransform3DRotate(CATransform3DIdentity, arrowAngle, 0, 0, 1) 
    arrowhead.transform = rotationZ 
    CATransaction.commit() 

    // Animate arrowhead scale 
    CATransaction.begin() 
    CATransaction.setAnimationDuration(1.5) 
    CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)) 
    arrowhead.transform = CATransform3DConcat(rotationZ, arrowheadTransformScale) 
    CATransaction.commit() 
+0

@马特有什么办法来实现动画图层的缩放和旋转不同持续时间? – dxb

+0

@matt我也试图用这种技术'arrowhead.setValue(arrowAngle,forKeyPath:“transform.rotation.z”)来转换特定的转换方面' – dxb

+0

@matt不需要整个动画使用'kCAMediaTimingFunctionLinear' ? – dxb

回答

1

这是工作:

override func viewDidLoad() { 

    let box = CALayer() 
    box.frame = CGRect(x: 150, y: 300, width: 100, height: 100) 
    box.backgroundColor = UIColor.white.cgColor 
    view.layer.addSublayer(box) 

    let boxTransform = box.transform 
    let currentAngle = atan2(boxTransform.m12, boxTransform.m11) 

    let currentScale = getScale(for: box.affineTransform()) 

    let targetAngle: CGFloat = .pi/3 
    let targetScale: CGFloat = 2 

    // Set layer model's animated properties to their target values. Then the subsequent animations don't require isRemovedOnCompletion and fillMode to be set which would leave the layer model out of sync. 
    var affineTransform = CGAffineTransform(rotationAngle: targetAngle) 
    affineTransform = affineTransform.scaledBy(x: targetScale, y: targetScale) 
    box.setAffineTransform(affineTransform) 

    let rotate = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotate.fromValue = currentAngle 
    rotate.toValue = targetAngle 
    rotate.duration = 2 
    rotate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 

    let scaleUp = CABasicAnimation(keyPath: "transform.scale") 
    scaleUp.fromValue = currentScale 
    scaleUp.toValue = targetScale 
    scaleUp.duration = 4 
    scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 

    let rotateAndScale = CAAnimationGroup() 
    rotateAndScale.animations = [rotate, scaleUp] 
    rotateAndScale.duration = 4 

    // Setting key to "transform" overwrites the implicit animation created when setting the target values before the animation. 
    box.add(rotateAndScale, forKey: "transform") 
} 

func getScale(for t: CGAffineTransform) -> CGFloat { 
    return sqrt(t.a * t.a + t.c * t.c) 
} 

Rotate and scale layer transform simultaneously