打字机效果文字动画

Posted

技术标签:

【中文标题】打字机效果文字动画【英文标题】:Typewriter effect text animation 【发布时间】:2015-01-02 01:24:22 【问题描述】:

我正在尝试使用 UILabel 创建打字机动画效果,但找不到任何答案。 UILabel 是正确使用的对象吗?我希望文本在屏幕上打印一个字符串数组,例如“登录...打开文件夹...重新启动系统..”等。我应该提到我是编码新手,我已经尝试搜索文档和 API 参考,但没有运气。如果值得一提,我目前正在学习 SWIFT

【问题讨论】:

Letter by letter animation for UILabel?的可能重复 【参考方案1】:

基于此答案: Letter by letter animation for UILabel?

我已将其更新到 Swift 4 并使用 DispatchWorkItem 解决了 CPU 动画问题,以便创建队列。

斯威夫特 4

extension UILabel 
    func setTextWithTypeAnimation(typedText: String, characterDelay: TimeInterval = 5.0) 
        text = ""
        var writingTask: DispatchWorkItem?
        writingTask = DispatchWorkItem  [weak weakSelf = self] in
            for character in typedText 
                DispatchQueue.main.async 
                    weakSelf?.text!.append(character)
                
                Thread.sleep(forTimeInterval: characterDelay/100)
            
        
        
        if let task = writingTask 
            let queue = DispatchQueue(label: "typespeed", qos: DispatchQoS.userInteractive)
            queue.asyncAfter(deadline: .now() + 0.05, execute: task)
        
    
    

用法

label.setTextWithTypeAnimation(typedText: text, characterDelay:  10) //less delay is faster

斯威夫特 5

func setTyping(text: String, characterDelay: TimeInterval = 5.0) 
  self.text = ""
    
  let writingTask = DispatchWorkItem  [weak self] in
    text.forEach  char in
      DispatchQueue.main.async 
        self?.text?.append(char)
      
      Thread.sleep(forTimeInterval: characterDelay/100)
    
  
    
  let queue: DispatchQueue = .init(label: "typespeed", qos: .userInteractive)
  queue.asyncAfter(deadline: .now() + 0.05, execute: writingTask)

用法

label.setTyping(text: "Your text")

【讨论】:

它似乎可以解决问题,问题是如果您在动画结束之前设置了一个新字符串。它将马铃薯的两根绳子粉碎在一起。如果有办法在开始新任务之前取消任务将是完美的。 @RyuuzakiJulio 我认为你可以禁用你的字符串输入源并在写入任务中创建一个计数器来检查它是否已经结束。也就是说,当计数器等于字符数时,输入将再次被启用。 @dimas-mendes 这是否意味着所有新输入都将被禁用,直到第一个动画完成?所以如果我有一个更重要的新文本出现,它会被忽略,直到上一条消息完成?有没有办法保留任务并在有新任务时取消它? @RyuuzakiJulio 是的,我不知道你的应用程序内部的逻辑,但我认为你可以创建一个临时结构来存储所有的写作任务,如果你需要取消,你可以调用“ workItem?.cancel()" 在每个待处理的任务上。 @dimas-mendes 我的应用程序对蓝牙/用户按钮按下事件作出反应。我有一个显示最新事件的“状态”标签,我认为有一个动画会很好。它确实有合理的逻辑,有一个消息列表并按顺序显示它们。我对您的解决方案的问题是任务是在 UILabel 扩展函数中创建的,因此一旦再次调用,就没有前一个任务的记录,您如何将它们存储在某个地方以便能够在新任务进入之前取消它们?我无法在 UILabel Extension 中创建任务数组。【参考方案2】:

更新:Xcode 7.0 GM • Swift 2.0

import UIKit

class ViewController: UIViewController 
    @IBOutlet weak var myTypeWriter: UITextField!
    let myText = Array("Hello World !!!".characters)
    var myCounter = 0
    var timer:NSTimer?
    func fireTimer()
        timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "typeLetter", userInfo: nil, repeats: true)
    
    func typeLetter()
        if myCounter < myText.count 
            myTypeWriter.text = myTypeWriter.text! + String(myText[myCounter])
            let randomInterval = Double((arc4random_uniform(8)+1))/20
            timer?.invalidate()
            timer = NSTimer.scheduledTimerWithTimeInterval(randomInterval, target: self, selector: "typeLetter", userInfo: nil, repeats: false)
         else 
            timer?.invalidate()
        
        myCounter++
    
    override func viewDidLoad() 
        super.viewDidLoad()
        fireTimer()
        // Do any additional setup after loading the view, typically from a nib.
    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

【讨论】:

不错。迫不及待想试试这个。 @Leo Dabus,致命错误:在展开可选值 (lldb) myTypeWriter.text = myTypeWriter.text 时意外发现 nil! + 字符串(myText[myCounter])【参考方案3】:

我编写了一个名为 CLTypingLabel 的 UILabel 子类,可在 GitHub 上找到。这应该可以满足您的需求。

安装 CocoaPods 后,在你的 Podfile 中添加如下类似的代码来使用它:

pod 'CLTypingLabel'

示例代码

将标签的类别从 UILabel 更改为 CLTypingLabel;

@IBOutlet weak var myTypeWriterLabel: CLTypingLabel!

在运行时,设置标签的文字会自动触发动画:

myTypeWriterLabel.text = "This is a demo of typing label animation..."

您可以自定义每个字符之间的时间间隔:

myTypeWriterLabel.charInterval = 0.08 //optional, default is 0.1

您可以随时暂停打字动画:

myTypeWriterLabel.pauseTyping() //this will pause the typing animation
myTypeWriterLabel.continueTyping() //this will continue paused typing animation

还有cocoapods自带的示例项目

【讨论】:

以上是关于打字机效果文字动画的主要内容,如果未能解决你的问题,请参考以下文章

干货|CSS3自动打字动画,让你的文字动起来!

从打字机效果的 N 种实现看JS定时器机制和前端动画

实现打字机动画的两种办法

实现打字机动画的两种办法

实现打字机动画的两种办法

AEJoy —— 表达式之闪烁光标的打字机效果JS