简体   繁体   English

如何在延迟后为UILabel的文本制作动画?

[英]How to animate UILabel's Text after delay?

I have a UIButton , and I would like to change its text by accessing its titleLabel attribute. 我有一个UIButton ,我想通过访问它的titleLabel属性来改变它的文本。 However, the way I want the button to change text is by first shrinking down to a very tiny size, then changing instantly while it's invisible, then scaling back up. 但是,我希望按钮改变文本的方式是首先缩小到非常小的尺寸,然后在它不可见时立即改变,然后缩小。 After looking through multiple posts on here, I have reached this: 在浏览了这里的多个帖子后,我达到了这个目的:

 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)

The problem is that this doesn't work. 问题是这不起作用。 What I get is a quick flash of the words "New Text" as the label shrinks, and then when it scales back up, it's still "Old Text". 我得到的是标签缩小时“New Text”字样的快速闪烁,然后当它缩小时,它仍然是“旧文本”。 It's so weird I can't even begin to wrap my head around what might be the cause. 这太奇怪了,我甚至无法开始围绕可能的原因。 I think what's happening is that it plays the reveal transition on the new text before it even shrinks down (No idea why since I specified duration=0), then grows back the old text. 我认为正在发生的事情是它在新文本甚至缩小之前播放新文本的显示转换(不知道为什么因为我指定的持续时间= 0),然后重新生成旧文本。

Here is what it looks like (with some background color change that I omitted above): 这是它的样子(我上面省略了一些背景颜色变化):

怪怪的Bug

First off, congratulations for including sound effects in your code comments, glad it's not just me that does that. 首先,祝贺您在代码评论中包含声音效果,很高兴不仅仅是我这样做。

The text property of a label cannot be animated, so it is applied immediately, spoiling your animation. 标签的text属性无法设置动画,因此会立即应用,从而破坏动画。

One solution, which I use a lot for complex animations, is to use snapshots. 我用于复杂动画的一个解决方案是使用快照。 At the start of the animation, create a snapshot of the label, then set the alpha of the label to zero and update the text. 在动画开始时,创建标签的快照,然后将标签的alpha设置为零并更新文本。 Then, animate the transforms of the label and snapshot together, when they're small, make the label visible and the snapshot invisible, then animate back up. 然后,将标签和快照的变换设置为动画,当它们很小时,使标签可见,快照不可见,然后进行动画备份。

That sounds more complicated than it is, here's code to run it in a 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()
}

Which gives you this result: 哪个给你这个结果:

在此输入图像描述

It's not clear to me what you are trying to do with the CATransition - unless there's another effect you're looking for as well, that isn't helping your cause. 我不清楚你想用CATransition做什么 - 除非你正在寻找另一种效果,这对你的事业没有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM