使用变换将CALayer旋转180度以上

时间:2015-02-19 21:44:47

标签: rotation core-animation calayer cabasicanimation catransform3d

我正在尝试将CALayer旋转一点点小于360度,而是变换将其旋转方向相反(即两个角度中较小的一个)。如果我还在图层上应用平移变换,我怎样才能实现这种旋转?此外,我希望能够控制旋转方向。似乎CAAnimation不会注意并采用较短的变换角度进行旋转。似乎这两个问题可能是相关的。以下是我的快速代码的部分内容:

func addAnimation() {
    var animation : CABasicAnimation = CABasicAnimation(keyPath: "transform")

    animation.delegate = self

    let translateDistY = CGRectGetMidY(self.view.bounds) - CGRectGetMidY(self.displayLayer.bounds)
    let rotationAngle = (CGFloat(M_PI*2.0) - 0.1)

    var transform : CATransform3D = CATransform3DMakeTranslation(0, translateDistY, 0)
    transform = CATransform3DRotate(transform, rotationAngle, 0, 0, 1)

    animation.fromValue = NSValue(CATransform3D: CATransform3DIdentity)
    animation.toValue = NSValue(CATransform3D: transform)

    animation.duration = 1.3
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

    let animStruct = animationStruct(animLayer: self.displayLayer, animation: animation, layerTransform: transform)

    self.animationSequence.append(animStruct)
}

func doAnimation() {
    if  animationSequence.count > 0 {
        let animStruct = animationSequence.removeAtIndex(0)
        animStruct.animLayer.transform = animStruct.layerTransform
        animStruct.animLayer.addAnimation(animStruct.animation, forKey: nil)
    }
}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
    self.doAnimation()
}

2 个答案:

答案 0 :(得分:0)

如果您喜欢使用普通变换动画,似乎没有任何旋转方法。一种方法是使用自定义图层属性。请看Nick Lockwood的这篇精彩文章。

http://www.objc.io/issue-12/animating-custom-layer-properties.html

答案 1 :(得分:0)

我对此问题有一些解决方案,但我不确定这是否正确或是否有更好的解决方案。尽管如此,这里遵循快速代码:

func addAnimation() {
    let translateByValueY = CGRectGetMidY(self.view.bounds) - CGRectGetMidY(self.diaplayLayer.bounds)

    var animRotateZ : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    animRotateZ.duration = 1.5
    animRotateZ.toValue = NSNumber(double: -0.2)
    animRotateZ.byValue = NSNumber(double: 2.0 * M_PI)
    animRotateZ.delegate = self
    animRotateZ.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    animRotateZ.setValue(self.diaplayLayer, forKey: "animationLayer")
    self.animationSequence.append(animRotateZ)

    var animTranslateY : CABasicAnimation = CABasicAnimation(keyPath: "transform.translation.y")

    animTranslateY.duration = 1.5
    animTranslateY.toValue = NSNumber(double: Double(CGRectGetMidY(self.view.bounds)))
    animTranslateY.byValue = NSNumber(double: Double(translateByValueY))
    animTranslateY.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    animTranslateY.setValue(self.diaplayLayer, forKey: "animationLayer")
    self.animationSequence.append(animTranslateY)

}

func doAnimation() {
    if animationSequence.count > 0 {
        let animRotateZ = animationSequence.removeAtIndex(0)
        let animationRotateZLayer = animRotateZ.valueForKey("animationLayer") as CALayer

        animationRotateZLayer.setValue(animRotateZ.toValue, forKeyPath: "transform.rotation.z")
        animationRotateZLayer.addAnimation(animRotateZ, forKey: animRotateZ.keyPath)

        let animTranslateY = animationSequence.removeAtIndex(0)
        let animationTranslateYLayer = animTranslateY.valueForKey("animationLayer") as CALayer

        animationTranslateYLayer.setValue(animTranslateY.toValue, forKeyPath: "transform.translation.y")
        animationTranslateYLayer.addAnimation(animTranslateY, forKey: animTranslateY.keyPath)
    }
}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
    self.doAnimation()
}

我从stackoverflow上的以下帖子中提取了大量信息,感谢他们:

Using CABasicAnimation to rotate a UIImageView more than once

How to chain different CAAnimation in an iOS application