2017-08-25 58 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