SwiftUI 中的 AVSpeechSynthesizerDelegate 实现

Ten*_*t66 2 avspeechsynthesizer ios13 swiftui

任何人都可以分享我们如何在 SwiftUI 中实现 AVSpeechSynthesizerDelegate。我们如何在 SwiftUI 应用程序中监听委托回调方法。

谢谢

Nei*_*ith 6

一种解决方案是定义一个符合ObservableObject. 这个想法是使用一个@Published属性来使 SwiftUI 能够更新您的 UI。这是跟踪状态的简单方法的示例AVSpeechSynthesizer(我不确定您的实际用例):

final class Speaker: NSObject, ObservableObject {
    
    @Published var state: State = .inactive
    
    enum State: String {
        case inactive, speaking, paused
    }

    override init() {
        super.init()
        synth.delegate = self
    }
    
    func speak(words: String) {
        synth.speak(.init(string: words))
    }
    
    private let synth: AVSpeechSynthesizer = .init()
    
}
Run Code Online (Sandbox Code Playgroud)

然后,使此类符合AVSpeechSynthesizerDelegate如下所示:

extension Speaker: AVSpeechSynthesizerDelegate {
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
        self.state = .speaking
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
        self.state = .paused
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        self.state = .inactive
    }
    
    // etc...
    
}
Run Code Online (Sandbox Code Playgroud)

在这里,我只是使用委托回调来更新单个@Published属性,但您可以根据您的用例在此处进行更新。ObservableObject使用s时要记住的要点是@Published,对您希望在值更改时驱动 UI 更新的任何属性使用属性包装器。这是一个示例视图:

struct MyView: View {
    
    @ObservedObject var speaker: Speaker
    
    var body: some View {
        // 1
        Text("State = \(speaker.state.rawValue)")
            .onReceive(speaker.$state) { state in
                // 2
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在 SwiftUI 中有两种使用@Published属性的方法View。1:简单读取值。SwiftUI 将在值更改时更新您的视图。2:使用@Published$前缀访问属性的发布者。使用ViewsonReceive方法,您可以在发布者发出值时执行代码。