如何知道AVSpeechUtterance何时完成,以便继续应用活动?

Con*_*sed 0 ios avspeechsynthesizer swift

当一个人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)
    }
}
Run Code Online (Sandbox Code Playgroud)

更新2:错误的解决方法......

使用上面提到的isSpeaking属性,在gameScene中:

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
    ]))
Run Code Online (Sandbox Code Playgroud)

kor*_*pok 8

委托模式是面向对象编程中最常用的设计模式之一,它并不像看起来那么难.对于您的情况,您可以简单地让您的类(游戏场景)成为CanSpeak类的委托.

protocol CanSpeakDelegate {
   func speechDidFinish()
}
Run Code Online (Sandbox Code Playgroud)

接下来将AVSpeechSynthesizerDelegate设置为CanSpeak类,声明CanSpeakDelegate然后使用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()
   }
}
Run Code Online (Sandbox Code Playgroud)

最后在您的游戏场景类中,简单地符合CanSpeakDelegate并将其设置为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
   }
}
Run Code Online (Sandbox Code Playgroud)