突出显示SwiftUI中的语音



我无法在SwiftUI中高亮显示文本话语。我只在UIKit中找到了它的例子。在UIKit它应该是var label: UILabel!,但在SwiftUI标签必须是字符串。我试图将NSMutableAttributedString转换成String格式,内部功能,但它抱怨。如何与String格式一起工作,使其在SwiftUI中也能工作?

import AVFoundation
class Speaker: NSObject {
let synth = AVSpeechSynthesizer()
var label: String // <- problem

override init() {
super.init()
synth.delegate = self
}
func speak(_ string: String) {
let utterance = AVSpeechUtterance(string: string)
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.4
synth.speak(utterance)
}

// Functions to highlight text
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
let mutableAttributedString = NSMutableAttributedString(string: utterance.speechString)
mutableAttributedString.addAttribute(.foregroundColor, value: UIColor.red, range: characterRange)
label.attributedText = mutableAttributedString
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
label.attributedText = NSAttributedString(string: utterance.speechString)
}
}

我建议您将UILabel包装在UIViewRepresentable中,以便您可以像以前一样继续使用有属性的字符串:


struct ContentView : View {
@ObservedObject var speaker = Speaker()

var body: some View {
VStack {
LabelRepresented(text: speaker.label)
}.onAppear {
speaker.speak("Hi. This is a test.")
}
}
}
struct LabelRepresented: UIViewRepresentable {
var text : NSAttributedString?

func makeUIView(context: Context) -> UILabel {
return UILabel()
}

func updateUIView(_ uiView: UILabel, context: Context) {
uiView.attributedText = text
}
}
class Speaker: NSObject, ObservableObject, AVSpeechSynthesizerDelegate {
let synth = AVSpeechSynthesizer()
@Published var label: NSAttributedString? // <- change to AttributedString

override init() {
super.init()
synth.delegate = self
}
func speak(_ string: String) {
let utterance = AVSpeechUtterance(string: string)
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.4
synth.speak(utterance)
}

// Functions to highlight text
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
let mutableAttributedString = NSMutableAttributedString(string: utterance.speechString)
mutableAttributedString.addAttribute(.foregroundColor, value: UIColor.red, range: characterRange)
label = mutableAttributedString
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
label = NSAttributedString(string: utterance.speechString)
}
}

我将label更改为NSAttributedString?,并将其更改为ObservableObject上的@Published属性——这样,当它更改时,视图会立即收到通知。

UIViewRepresentable创建一个标签,并在任何时候使用属性字符串更新它。

如果你确实想尝试更纯粹的SwiftUI方法,这篇博客文章有一些在SwiftUI中使用NSAttributedString的好资源(包括我采用的方法):https://swiftui-lab.com/attributed-strings-with-swiftui/

最新更新