在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的扩展。

我们要做的是

  1. 为字符数组和将要增加的当前索引创建值。 它将从0开始,并且每次迭代都会增加
  2. 创建我们上面所做的计时器
  3. 将characterArray [characterIndex]中的字符追加到UILabel的文本上
  4. 将characterIndex向上一级递增,以使添加到下一个迭代的字符将是数组中的下一个字符
  5. 检查一下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,可在此处获取。