当一个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
   }
}

10-04 17:09