我无法在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/