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

时间:2016-11-29 00:48:14

标签: ios swift avspeechsynthesizer

AVSpeechUtterance说话时,我想等到它完成之后再做其他事情。

AVSpeechSynthesizer的财产似乎表明发言时间:

isSpeaking

这个问题听起来很愚蠢和简单,我想知道如何使用/检查这个属性,等到语音结束后再继续?

可替换地:

有一个代表,我对如何使用也毫无头绪,它有能力在话语结束时做某事:

AVSpeechSynthesizerDelegate

有一个答案,here,说要使用它。但这对我没有帮助,因为我不知道如何使用代表。

UPDATE:

这就是我设置口语课的方式:

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属性,在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
    ]))

3 个答案:

答案 0 :(得分:7)

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

protocol CanSpeakDelegate {
   func speechDidFinish()
}

接下来将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()
   }
}

最后,在您的游戏场景类中,只需符合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
   }
}

答案 1 :(得分:1)

设置AVSpeechSynthesizer实例的委托。

voiceSynth.delegate = self

然后,实现didFinish方法如下:

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, 
                  didFinish utterance: AVSpeechUtterance) {
    // Implements here.
}

答案 2 :(得分:-1)

使用方法尝试AVSpeechSynthesizerDelegate

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance;