在 swift 中为旋转标签设置动画?

Animate a rotated label in swift?

我正在尝试为这样的旋转标签制作动画:

@IBOutlet fileprivate weak var loadingLabel: UILabel!

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        loadingLabel.transform = CGAffineTransform(rotationAngle: CGFloat(0.2))  // rotation line

        UIView.animate(withDuration: 2.0, animations: {
            self.loadingLabel.transform = CGAffineTransform(translationX: 0, y: self.view.bounds.size.height)
        })
    }

当我注释掉代码的旋转行(并保持标签不旋转)时,它工作正常。但是当我旋转它时,标签会在动画开始时离开屏幕:

当我注释掉动画时,标签旋转得很好(但显然没有动画):

如何在没有这种奇怪的位置的情况下旋转图像并为其设置动画?

编辑:澄清一下:我希望标签开始在屏幕中央旋转,只需简单地移动标签即可。我不想在动画期间旋转图像。

第一个变换不是动画块,这就是它从屏幕开始的原因。 您应该将它移动到动画块中,然后使用完成处理程序再次设置动画。

UIView.animate(withDuration: 2.0, animations: {
    //
}, completion: { (result) in
    //
})
  • 注意,角度以弧度为单位。

您可以使用 CABasicAnimation 执行动画,因为它可以让您更好地控制动画,并且它有一个完成块,您可以根据需要在上面隐藏标签.

    loadingLabel.transform = CGAffineTransform(rotationAngle: CGFloat(0.2))  // rotation line

        let animationKey = "position.y"
        CATransaction.begin()
        let moveYAnimation = CABasicAnimation( keyPath:  animationKey)
        moveYAnimation.fromValue = loadingLabel.frame.origin.y
        moveYAnimation.toValue = self.view.bounds.size.height
        moveYAnimation.duration = 2
        loadingLabel.layer.add( moveYAnimation, forKey: animationKey )

        // Callback function
        CATransaction.setCompletionBlock {
            print("end animation")
            self.loadingLabel.isHidden = true
        }

        // Do the actual animation and commit the transaction
        loadingLabel.layer.add(moveYAnimation, forKey: animationKey)
        CATransaction.commit()

希望对您有所帮助。

正确答案是您应该连接变换矩阵。如果你不想做线性代数那么简单的方法是你使用变换来设置旋转而不是动画它,然后动画视图的 frame/center 代替。

import UIKit

class V: UIViewController {
    @IBOutlet var label: UILabel!
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        label.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 6)
        label.center.x += 300
        UIView.animate(withDuration: 2) {
            self.label.center.x -= 300
        }
    }
}