如何在Swift中控制动画旋转方向超过180 °?

cnwbcb6i  于 2023-02-15  发布在  Swift
关注(0)|答案(4)|浏览(163)

根据rotated(by:)的文档:

旋转仿射变换的Angular (以弧度为单位)。在iOS中,正值指定逆时针旋转,负值指定顺时针旋转。
这引起了很多混乱,并且已经得到了部分解答,但是即使我们接受坐标系被翻转(并且只是按照文档所述的相反操作),在设置动画时仍然会提供不一致的结果。
旋转方向(顺时针或逆时针)取决于目标旋转与当前旋转的接近程度:

  • <= 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))
}
iezvtpos

iezvtpos1#

试试这个:

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

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

wrrgggsh2#

答案是使用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")
w46czmvw

w46czmvw3#

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")
    }
gojuced7

gojuced74#

第三个选项允许您在所需方向上旋转180º:

// #1 This rotates 90º clockwise
        UIView.animate(withDuration: 0.25, animations:{
            view.transform = CGAffineTransform(rotationAngle: -CGFloat.pi/2)
        })
        
        // #2 This rotates 90º counter clockwise back to #1
        UIView.animate(withDuration: 0.25, animations:{
            view.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
        })
        
        // #3 This rotates 270º clockwise back to #1
        UIView.animate(withDuration: 0.1875, animations:{
            view.transform = CGAffineTransform(rotationAngle: CGFloat.pi/2)
        }, completion: { _ in
            UIView.animate(withDuration: 0.0625, animations:{
                view.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
            })
        })

相关问题