当一个AVSpeechUtterance
正在讲话时,我想等到它完成后再做其他事情。
有一个AVSpeechSynthesizer
的属性似乎表明了什么时候说话:isSpeaking
尽管这个问题听起来既愚蠢又简单,但我想知道如何使用/检查这个属性,直到演讲结束后再继续?
或者:
有一个代表,我也不知道如何使用,它有能力在话语结束时做某事:AVSpeechSynthesizerDelegate
有一个答案,说要用这个。但这对我没有帮助,因为我不知道如何使用代表。
更新:
我就是这样安排我的口语课的:
import AVFoundation
class CanSpeak: NSObject, AVSpeechSynthesizerDelegate {
let voices = AVSpeechSynthesisVoice.speechVoices()
let voiceSynth = AVSpeechSynthesizer()
var voiceToUse: AVSpeechSynthesisVoice?
override init(){
voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Karen" }).first
}
func sayThis(_ phrase: String){
let utterance = AVSpeechUtterance(string: phrase)
utterance.voice = voiceToUse
utterance.rate = 0.5
voiceSynth.speak(utterance)
}
}
更新2:错误的解决方法。。。
在游戏场景中使用上述
isSpeaking
属性:voice.sayThis(targetsToSay)
let initialPause = SKAction.wait(forDuration: 1.0)
let holdWhileSpeaking = SKAction.run {
while self.voice.voiceSynth.isSpeaking {print("STILL SPEAKING!")}
}
let pauseAfterSpeaking = SKAction.wait(forDuration: 0.5)
let doneSpeaking = SKAction.run {print("TIME TO GET ON WITH IT!!!")}
run(SKAction.sequence(
[ initialPause,
holdWhileSpeaking,
pauseAfterSpeaking,
doneSpeaking
]))
最佳答案
委托模式是面向对象编程中最常用的设计模式之一,它并不像看起来那么难。对于您的情况,您可以简单地让您的类(游戏场景)成为CanSpeak类的代表。
protocol CanSpeakDelegate {
func speechDidFinish()
}
接下来将AVSpeechSynthesizerDelegate设置为CanSpeak类,声明CanSpeak delegate,然后使用AVSpeechSynthesizerDelegate函数。
class CanSpeak: NSObject, AVSpeechSynthesizerDelegate {
let voices = AVSpeechSynthesisVoice.speechVoices()
let voiceSynth = AVSpeechSynthesizer()
var voiceToUse: AVSpeechSynthesisVoice?
var delegate: CanSpeakDelegate!
override init(){
voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Karen" }).first
self.voiceSynth.delegate = self
}
func sayThis(_ phrase: String){
let utterance = AVSpeechUtterance(string: phrase)
utterance.voice = voiceToUse
utterance.rate = 0.5
voiceSynth.speak(utterance)
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
self.delegate.speechDidFinish()
}
}
最后,在游戏场景类中,只需遵循CanSpeak delegate并将其设置为CanSpeak类的委托。
class GameScene: NSObject, CanSpeakDelegate {
let canSpeak = CanSpeak()
override init() {
self.canSpeak.delegate = self
}
// This function will be called every time a speech finishes
func speechDidFinish() {
// Do something
}
}