如何控制Swift超过180º的动画旋转方向?

时间:2016-12-16 10:33:47

标签: ios swift animation

根据rotated(by:)的{​​{3}}:

  

角度

     

以弧度表示旋转仿射变换的角度。在iOS中,正值指定逆时针旋转,负值指定顺时针旋转。

这引起了很多混乱,并且已经documentation,但即使我们接受坐标系被翻转(并且只是与文档所说的相反),它仍然会在动画时提供不一致的结果。 / p>

旋转方向 - 顺时针或逆时针 - 取决于目标旋转与当前旋转的接近程度:

  • <= 180º顺时针动画
  • > 180º逆时针动画

使用UIView.animateUIViewPropertyAnimator显示不一致:

// Animates CLOCKWISE
UIView.animate(withDuration: 2.0) {
    let radians = Angle(179).radians // 3.12413936106985
    view.transform = view.transform.rotated(by: CGFloat(radians))
}
// Animates COUNTER-CLOCKWISE
UIViewPropertyAnimator(duration: 2, curve: .linear) {
    let radians = Angle(181).radians // 3.15904594610974
    view.transform = view.transform.rotated(by: CGFloat(radians))
}
// Does not animate
UIViewPropertyAnimator(duration: 2, curve: .linear) {
    let radians = Angle(360).radians // 6.28318530717959
    view.transform = view.transform.rotated(by: CGFloat(radians))
}

3 个答案:

答案 0 :(得分:2)

答案是使用CABasicAnimation进行180º以上的旋转,请记住正值是顺时针负值是逆时针

// Rotate 360º clockwise.
let rotate = CABasicAnimation(keyPath: "transform.rotation")
rotate.fromValue = Angle(0).radians
rotate.toValue = Angle(360).radians
rotate.duration = 2.0
self.layer.add(rotate, forKey: "transform.rotation")

答案 1 :(得分:0)

    if sender.isSelected {
        /// clockwise
        let rotate = CABasicAnimation(keyPath: "transform.rotation")
        rotate.fromValue = 0
        rotate.toValue = CGFloat.pi
        rotate.duration = 0.25
        rotate.fillMode = CAMediaTimingFillMode.forwards
        rotate.isRemovedOnCompletion = false
        self.arrowButton.layer.add(rotate, forKey: "transform.rotation")
    } else {
        /// anticlockwise
        let rotate = CABasicAnimation(keyPath: "transform.rotation")
        rotate.fromValue = CGFloat.pi
        rotate.toValue = 0
        rotate.duration = 0.25
        rotate.fillMode = CAMediaTimingFillMode.forwards
        rotate.isRemovedOnCompletion = false
        self.arrowButton.layer.add(rotate, forKey: "transform.rotation")
    }

答案 2 :(得分:0)

尝试一下:

    let multiplier: Double = isSelected ? 1 : -2
    let angle = CGFloat(multiplier * Double.pi)

    UIView.animate(withDuration: 0.4) {
        self.indicatorImageView.transform = CGAffineTransform(rotationAngle: angle)
    }