UIView.animate(withDuration:2.0, animations: {
self.imageView.transform = CGAffineTransform(rotationAngle: (270 * CGFloat(2 * Double.pi)) / 360.0)
})
这个动画是逆时针旋转的,我想让它顺时针旋转。
要顺时针旋转270度...
UIView.animate(withDuration:2.0, animations: {
self.sampleView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
self.sampleView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi * 3 / 2))
})
postfix operator °
protocol IntegerInitializable: ExpressibleByIntegerLiteral {
init (_: Int)
}
extension Int: IntegerInitializable {
postfix public static func °(lhs: Int) -> CGFloat {
return CGFloat(lhs) * .pi / 180
}
}
extension CGFloat: IntegerInitializable {
postfix public static func °(lhs: CGFloat) -> CGFloat {
return lhs * .pi / 180
}
}
2) 使用 CABasicAnimation
实现任意角度旋转:
extension UIView {
func rotateWithAnimation(angle: CGFloat, duration: CGFloat? = nil) {
let pathAnimation = CABasicAnimation(keyPath: "transform.rotation")
pathAnimation.duration = CFTimeInterval(duration ?? 2.0)
pathAnimation.fromValue = 0
pathAnimation.toValue = angle
pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
self.transform = transform.rotated(by: angle)
self.layer.add(pathAnimation, forKey: "transform.rotation")
}
}
使用方法:
override func viewDidAppear(_ animated: Bool) {
// clockwise
myView.rotateWithAnimation(angle: 90°)
// counter-clockwise
myView.rotateWithAnimation(angle: -270°)
}
isRemovedOnCompletion = false
和fillMode = kCAFillModeForwards
相结合并不是一种使动画“固定”的好方法,主要是因为它会使图层属性与其在屏幕上显示的方式之间的差异随时间而持续存在,这可能会导致错误。更强大、最佳的做法是在添加动画前更新图层属性,然后让动画在完成时自行删除。 - David Rönnqvist解释
旋转的问题在于它会找到完成旋转的最短路径。 因此,当您的视图在开始时旋转了0度时,旋转该视图至270度的最短路径是将视图旋转-90度。
您需要结合两个动画来完成这个过程。
第一个: 将视图旋转180 + 1度 (加1告诉动画您想顺时针旋转-更短的路径)
第二个: 将视图旋转90度
在代码中:
假设您有一个名为rotateView的UIView。
@objc func rotate() {
if rotateView.transform == .identity {
UIView.animate(withDuration: 0.5) {
self.rotateView.transform = CGAffineTransform(rotationAngle: (CGFloat.pi) + 1)
}
UIView.animate(withDuration: 0.5, delay: 0.25, options:[], animations: {
self.rotateView.transform = CGAffineTransform(rotationAngle: (CGFloat.pi / 2))
}, completion: nil)
} else {
UIView.animate(withDuration: 0.5, animations: {
self.rotateView.transform = .identity
})
}
}