在Swift中实现键入文字效果
过去,在进行配音之前,视频游戏中的文字会在屏幕上键入。 通过逐段显示单词来模拟说单词所花费的时间,从而对文本产生了语音影响。
如今,效果仍在使用。 例如,Cleverbot是一种出于相同原因在文本上使用文字的AI,可以在没有语音时模拟语音。 该效果很容易实现,尽管要花点时间才能理解。 让我们一起完成所有步骤,让我们的程序说话!
计时器和ScheduledTimer
计时器是一种Swift工具,可让开发人员以一定的时间间隔遍历项目。 有多种使用Timer的方法,但现在让我们集中讨论ScheduledTimer函数。
Timer.scheduledTimer(withTimeInterval:TimeInterval,重复:Bool,块:(Timer)-> Void))
计划计时器的三个参数是1)withTimeInterval,它确定计时器首次触发之前需要等待多长时间,以及每次计时器触发之间有多少时间,2)重复,以确定计时器是否触发一次以上,和3)块,这是一个闭包,它确定计时器触发时要确切执行的操作。 您应该注意,这种关闭也使我们可以访问该块中的计时器本身。 稍后将很重要。
现在,我们将使用带有以下参数的计时器:
Timer.scheduledTimer(withTimeInterval:0.1,重复:true){(timer)in
}
如果愿意,您可以从中创建一个变量,以访问其他作用域中的计时器。 但是我们现在没有用了,所以就别管它了。
现在我们有了一个计时器,它将每0.1秒触发一次。 有了一点技术知识,我们就继续前进。
获取字符串和字符
首先,让我们创建一个字符串,一个字符一个字符地将要输入的消息。
let message =“跟我来,看看预言中的事情...”
预言。
但是字符串只会带我们走那么远。 我们需要能够逐个字符地访问字符串。 大概有上千种方法可以做到,其中一半可能比我将要使用的方法效率更高,但是我们只需要将它们放入数组即可,所以……
扩展字符串{
var characterArray:[Character] {
var characterArray = [Character]()
用于self.characters中的字符{
characterArray.append(字符)
}
返回characterArray
}
}
有了我们所有的工具,让我们开始吧。
写出代码块
让我们将计时器放入函数中。 对于这种情况,让我们将其作为UITextView的扩展。
我们要做的是
- 为字符数组和将要增加的当前索引创建值。 它将从0开始,并且每次迭代都会增加
- 创建我们上面所做的计时器
- 将characterArray [characterIndex]中的字符追加到UILabel的文本上
- 将characterIndex向上一级递增,以使添加到下一个迭代的字符将是数组中的下一个字符
- 检查一下characterIndex是否已经使characterArray.count黯然失色,如果已经超过了该值,则使计时器无效,以使其不再触发。
看起来像这样:
扩展UITextView {
func typeOn(string:String){
让characterArray = string.characterArray
var characterIndex = 0
Timer.scheduledTimer(withTimeInterval:0.1,重复:true){(timer)in
self.text.append(characterArray [characterIndex])
characterIndex + = 1
如果characterIndex == characterArray.count {
timer.invalidate()
}
}
}
}
试试看! 您将在UITextView上看到基本的键入效果。 好漂亮!
改进基础
此功能的作用很好,但仍然有些笨拙。 感觉就像是机器人,而不是讲话。 最大的问题是,空格字符和字母所花费的时间一样长。 为了使这种感觉更加自然,让我们添加几行代码,使我们可以跳过一个空格。 这个简单的while循环会很好地执行。
扩展UITextView {
func typeOn(string:String){
让characterArray = string.characterArray
var characterIndex = 0
Timer.scheduledTimer(withTimeInterval:0.1,重复:true){(timer)in
而characterArray [characterIndex] ==“” {
self.text.append(“”)
characterIndex + = 1
如果characterIndex == characterArray.count {
timer.invalidate()
返回
}
}
self.text.append(characterArray [characterIndex])
characterIndex + = 1
如果characterIndex == characterArray.count {
timer.invalidate()
}
}
}
}
现在再次运行它。 您会看到流程更好,更自然。 句号和逗号仍会占用时间,但这是有道理的,因为考虑到这些或多或少代表了讲话的自然中断。
作为最后的繁荣,让我们创建一种创建暂停的方法。 我们在这里的信息不祥,所显示的文字应该笼罩着读者。 如果我们在“跟我来”之后以及省略号的每个句号之间添加一个停顿,那将使我们的信息更加不祥。
要做到这一点,让我们创建一个函数可以识别的字符,然后在看到该字符时,它将跳过计时器迭代的所有其余代码。 我根本不打算在文本中使用美元符号,因此让我们回到字符串并在需要暂停的地方添加“ $”。
let message =“跟我来$$$,看看已经预言了$。$$$。$$$$$。”
并在代码中使用if语句进行说明,这将检查字符是否为“ $”,如果是,则不向UITextView添加任何内容。
扩展UITextView {
func typeOn(string:String){
让characterArray = string.characterArray
var characterIndex = 0
Timer.scheduledTimer(withTimeInterval:0.1,重复:true){(timer)in
如果characterArray [characterIndex]!=“ $” {
而characterArray [characterIndex] ==“” {
self.text.append(“”)
characterIndex + = 1
如果characterIndex == characterArray.count {
timer.invalidate()
返回
}
}
self.text.append(characterArray [characterIndex])
}
characterIndex + = 1
如果characterIndex == characterArray.count {
timer.invalidate()
}
}
}
}
现在,借助此功能,我们可以看到文本表达语音中止的能力。
多玩一些,看看是否可以使您的讲话更加自然!
字体为Kongtext,可在此处获取。