Ios 打字机效果文本动画

Ios 打字机效果文本动画,ios,swift,Ios,Swift,我正在尝试用UILabel创建打字机动画效果,但找不到任何答案。UILabel是否是要使用的正确对象?我希望文本打印到屏幕上的字符串数组,如“登录…打开文件夹…重新启动系统…”等。我应该提到,我是新的编码,我已经尝试搜索文档和API参考,但没有运气。如果值得一提的话,我目前正在学习SWIFT更新:Xcode 7.0 GM•SWIFT 2.0 import UIKit class ViewController: UIViewController { @IBOutlet weak var

我正在尝试用UILabel创建打字机动画效果,但找不到任何答案。UILabel是否是要使用的正确对象?我希望文本打印到屏幕上的字符串数组,如“登录…打开文件夹…重新启动系统…”等。我应该提到,我是新的编码,我已经尝试搜索文档和API参考,但没有运气。如果值得一提的话,我目前正在学习SWIFT更新: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.
    }
}
导入UIKit
类ViewController:UIViewController{
@IBVAR我的打字机:UITextField!
让myText=Array(“Hello World!!!”。字符)
var myCounter=0
变量计时器:NSTimer?
func fireTimer(){
timer=NSTimer.scheduledTimerWithTimeInterval(0.5,目标:self,选择器:“typeLetter”,用户信息:nil,重复:true)
}
func typeLetter(){
如果myCounter
我编写了UILabel的一个子类,名为,可在GitHub上获得。这应该是你想要的

安装CocoaPods后,将以下内容添加到您的Podfile中以使用它:

pod 'CLTypingLabel'
示例代码 将标签的类别从UILabel更改为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
还有一个基于此答案的示例项目

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

Swift 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

Swift 5

func setTyping(文本:字符串,字符延迟:时间间隔=5.0){
self.text=“”
让writingTask=DispatchWorkItem{[weak self]进入
text.forEach{char in
DispatchQueue.main.async{
self?.text?.append(字符)
}
线程睡眠(forTimeInterval:characterDelay/100)
}
}
let队列:DispatchQueue=.init(标签:“typespeed”,qos:.userInteractive)
queue.asyncAfter(截止日期:.now()+0.05,执行:writingTask)
}
用法

label.setTextWithTypeAnimation(typedText: text, characterDelay:  10) //less delay is faster
label.setTyping(文本:“您的文本”)

不错。迫不及待地想试试这个。@Leo Dabus,致命错误:在展开可选值(lldb)myTypeWriter.text=myTypeWriter.text!+字符串(myText[myCounter])它的可能副本似乎确实起到了作用,问题是如果在动画结束之前设置了一个新字符串。它会把两根绳子砸在一起。如果有办法在开始新任务之前取消该任务,那就太好了。@ryuuuuzakijulio我认为您可以禁用字符串输入源,并在写入任务中创建一个计数器,以检查它是否已结束。换句话说,当计数器等于字符数时,输入将再次启用。@dimas mendes这是否意味着在第一个动画完成之前,所有新输入都将被禁用?因此,如果我有一个更重要的新文本出现,它将被忽略,直到上一条消息完成?有没有办法保留任务并在新任务到来时取消它?@RyuuzakiJulio是的,我不知道你的应用程序中的逻辑,但我认为你可以创建一个临时结构来存储所有的写作任务,如果你需要取消,你可以调用“workItem?.cancel()在每个挂起的任务上。@dimas修复我的应用程序对蓝牙/用户按钮按下事件作出反应。我有一个“状态”标签,显示最新的事件,我想有一个动画会很好。有一个消息列表并按顺序显示,这听起来很有逻辑。我对您的解决方案的问题是,任务是在UILabel扩展函数中创建的,因此再次调用时,没有上一个任务的记录,您如何将它们存储在某个位置,以便在新任务到来之前取消它们?我无法在UILabel扩展中创建任务数组。