【问题标题】:AVSpeechSynthesiser bugging ViewDidLoad functionAVSpeechSynthesiser 窃听 ViewDidLoad 函数
【发布时间】:2018-06-15 14:16:59
【问题描述】:

每当我导航到这个视图控制器时,viewDidLoad 中的 speakText() 函数由于某种原因不起作用,并且视图控制器需要很长时间才能加载(当我删除该行时不是这种情况)。在该行上方,文本标签的文本设置为要朗读的字符串,并且工作正常。每次调用recordTapped,语音合成都能完美运行。但是,它似乎在viewDidLoad 中不起作用。

更新在分配语音合成器的视图控制器委托并异步运行该功能后,我做了更多测试。但是,它不起作用。我将视图控制器设置为初始视图控制器,它仍然不起作用,所以导航不是问题,加载时间仍然很长。

import UIKit
import AVFoundation

class StartViewController: UIViewController, AVAudioRecorderDelegate {

    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var recordButton: UIButton!
    let synth = AVSpeechSynthesizer()
    var myUtterance = AVSpeechUtterance(string: "")
    var number = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        synth.delegate? = self as! AVSpeechSynthesizerDelegate
        number = 0
        DispatchQueue.global(qos: .userInitiated).async       {self.speakText(int: number)}
        self.number = self.number + 1
    }

    @IBAction func recordTapped(_ sender: UIButton) {
        speakText(int: number)
        number = number + 1
    }

    func speakText(int: Int) {

    myUtterance = AVSpeechUtterance(string: "the number is \(int)")
    myUtterance.voice = AVSpeechSynthesisVoice(language: "en-AU")
    synth.speak(myUtterance)

    }

}

【问题讨论】:

  • 您能否尝试使用多线程来满足您的语音需求?您正在从主线程调用语音,这可能是一个问题。尝试使用 global -> userInteractive/ userInitiated queues,如果它有效,请告诉我。
  • 还可以尝试在 viewDidLoad() 中调用之前将 Speech 的委托设置为 Vc(自身),然后检查。
  • 更新问题。

标签: swift xcode avfoundation avspeechsynthesizer avspeechutterance


【解决方案1】:

正如我在 cmets 中所说,多线程有效。刚刚测试了自己。工作代码如下,请测试确认。依靠单独的线程进行语音总是好的。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var recordButton: UIButton!

    var number = 0

    @IBAction func recordTapped(_ sender: UIButton) {
        questionLabel.text = "\(number)"
        speakTest(int: number)
        number += 1
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        number = 0
        questionLabel.text = "\(number)"
        DispatchQueue.global(qos: .userInitiated).async {
            self.speakTest(int: self.number)
        }
//        speakTest(int: number)

        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func speakTest(int: Int) {
        let utterance = AVSpeechUtterance(string: "Number is \(int)")
        let synth = AVSpeechSynthesizer()
        synth.speak(utterance)
    }
}

Plus,要在视图出现时调用 Speech,请从 viewWillAppear()viewDidAppear() 调用它,而不是从 viewDidLoad() 调用,因为后者在应用程序处于前台时调用一次。

【讨论】:

  • 感谢您的回复,我更新了我的问题,因为它仍然无法正常工作。
  • 你用过GCD吗?正在为我工​​作。不过感谢您的更新。会检查
  • 我不确定您所说的 GCD 是什么意思,但是,视图控制器需要很长时间才能加载,但只是第一次。一旦我导航到前一个视图控制器并返回它,它就会立即加载。
  • 更新问题再次合并您的代码,也许我做错了什么?
  • viewDidLoad 函数不会在您切换 viewController 时一次又一次地被调用。 viewDidAppear 以这种方式被调用。尝试从 viewDidAppear/viewWillAppear 调用语音函数,并告诉我它是否有效。
猜你喜欢
  • 1970-01-01
  • 2011-04-06
  • 2015-01-13
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
相关资源
最近更新 更多