延迟后如何为 UILabel 文本设置动画?

How to animate UILabel's Text after delay?

我有一个 UIButton,我想通过访问它的 titleLabel 属性来更改它的文本。但是,我希望按钮更改文本的方式是首先缩小到非常小的尺寸,然后在它不可见时立即更改,然后再按比例缩小。浏览了这里的多个帖子后,我得到了这个:

 let changeText = CATransition();
    changeText.type = kCATransitionReveal;
    changeText.duration = 0.0;
    changeText.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionLinear);
    submitButton.titleLabel?.layer.add(changeText, forKey: "changeTextTransition");


    UIView.animateKeyframes(withDuration: 0.6, delay: 0, options: .calculationModeLinear, animations: {
        //Zzzeeeewwwwwwwwww
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: {
            self.submitButton.titleLabel?.transform = self.submitButton.titleLabel!.transform.scaledBy(x: 0.001, y: 0.001);
        })


        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.0, animations: {
            self.submitButton.titleLabel?.text = "Green";
        })

        //Wwwwwweeeeeeyyyyyppp
        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
            self.submitButton.titleLabel?.transform = self.submitButton.titleLabel!.transform.scaledBy(x: 1000, y: 1000);
        })
    }, completion: nil)

问题是这不起作用。当标签缩小时,我得到的是 "New Text" 字样的快速闪现,然后当它按比例放大时,它仍然是 "Old Text"。这太奇怪了,我什至无法开始思考可能是什么原因。我认为发生的事情是它在新文本缩小之前播放显示过渡(不知道为什么因为我指定了持续时间=0),然后又长回旧文本。

这是它的样子(我在上面省略了一些背景颜色变化):

首先,恭喜您在代码注释中加入了音效,很高兴不只是我这样做。

标签的文本 属性 无法设置动画,因此会立即应用,破坏您的动画效果。

我在复杂动画中经常使用的一个解决方案是使用快照。在动画开始时,创建标签的快照,然后将标签的 alpha 设置为零并更新文本。然后,一起对标签和快照的变换进行动画处理,当它们很小时,使标签可见而快照不可见,然后再进行动画处理。

这听起来比实际更复杂,下面是 运行 在 playground 中的代码:

import UIKit
import PlaygroundSupport

let view = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
view.backgroundColor = .blue
PlaygroundPage.current.liveView = view

let label = UILabel(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
label.text = "Hello"
label.font = UIFont.systemFont(ofSize: 50)
label.textAlignment = .center
label.textColor = .white
view.addSubview(label)

let snapshot = label.snapshotView(afterScreenUpdates: true)!
view.addSubview(snapshot)
snapshot.frame = label.frame
label.alpha = 0
label.text = "Goodbye"

UIView.animateKeyframes(withDuration: 2, delay: 0, options: [.repeat, .autoreverse], animations: { 
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.45) {
        label.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
        snapshot.transform = label.transform
    }

    UIView.addKeyframe(withRelativeStartTime: 0.45, relativeDuration: 0.1) {
        label.alpha = 1.0
        snapshot.alpha = 0.0
    }

    UIView.addKeyframe(withRelativeStartTime: 0.55, relativeDuration: 0.45) {
        label.transform = CGAffineTransform.identity
    }
}) { _ in
    snapshot.removeFromSuperview()
}

这给你这个结果:

我不清楚你想用 CATransition 做什么 - 除非你也在寻找另一种效果,否则这对你的事业没有帮助。