SwiftUI中的Higlight语音发声 [英] Higlight speech utterance in SwiftUI
问题描述
我没有在SwiftUI中突出显示文本说话.我仅在UIKit中找到了它的示例.在UIKit中,它应该是 var标签:UILabel!
,但是在SwiftUI中,标签必须是String.我试图在函数内部将 NSMutableAttributedString
转换为 String
格式,但这很麻烦.如何使用 String
格式进行计算,使其也可以在SwiftUI中使用?
导入AVFoundation演讲者:NSObject {令synth = AVSpeechSynthesizer()var label:字符串//<-问题覆盖init(){super.init()synth.delegate =自我}func talk(_ string:String){let话语= AVSpeechUtterance(字符串:字符串)utterance.voice = AVSpeechSynthesisVoice(语言:"en-GB")话语率= 0.4synth.speak(话语)}//突出显示文字的功能func speechSynthesizer(_合成器:AVSpeechSynthesizer,willSpeakRangeOfSpeechString characterRange:NSRange,语音:AVSpeechUtterance){让mutableAttributedString = NSMutableAttributedString(string:utterance.speechString)mutableAttributedString.addAttribute(.foregroundColor,值:UIColor.red,范围:characterRange)label.attributedText = mutableAttributedString}func speechSynthesizer(_合成器:AVSpeechSynthesizer,didFinish话语:AVSpeechUtterance){label.attributedText = NSAttributedString(string:utterance.speechString)}}
我建议您将 UILabel
包装在 UIViewRepresentable
中,以便可以像以前一样继续使用属性字符串:
struct ContentView:查看{@ObservedObject var扬声器= Speaker()var body:some View {VStack {LabelRepresented(文字:speaker.label)} .onAppear {Speaker.speak(嗨.这是一个测试.")}}}struct LabelRepresented:UIViewRepresentable {var文字:NSAttributedString?func makeUIView(context:Context)->UILabel {返回UILabel()}func updateUIView(_ uiView:UILabel,context:Context){uiView.attributedText =文本}}演讲者类:NSObject,ObservableObject,AVSpeechSynthesizerDelegate {令synth = AVSpeechSynthesizer()@Published var标签:NSAttributedString?//<-更改为AttributedString覆盖init(){super.init()synth.delegate =自我}func talk(_ string:String){let话语= AVSpeechUtterance(字符串:字符串)utterance.voice = AVSpeechSynthesisVoice(语言:"en-GB")话语率= 0.4synth.speak(话语)}//突出显示文字的功能func speechSynthesizer(_合成器:AVSpeechSynthesizer,willSpeakRangeOfSpeechString characterRange:NSRange,语音:AVSpeechUtterance){让mutableAttributedString = NSMutableAttributedString(string:utterance.speechString)mutableAttributedString.addAttribute(.foregroundColor,值:UIColor.red,范围:characterRange)标签= mutableAttributedString}func speechSynthesizer(_合成器:AVSpeechSynthesizer,didFinish话语:AVSpeechUtterance){标签= NSAttributedString(字符串:utterance.speechString)}}
我将 label
更改为 NSAttributedString?
,并将其设置为 ObservableObject
上的@Published属性-这样,当更改时,该视图会立即得到通知.
UIViewRepresentable
创建一个标签,并在更改时使用属性字符串对其进行更新.
如果您想尝试更纯净的SwiftUI方法,此博客文章提供了一些在SwiftUI中使用NSAttributedString的良好资源(包括我采用的方法): 解决方案
I suggest you wrap UILabel
in UIViewRepresentable
so that you can keep using an attributed string like before:
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)
}
}
I changed label
into an NSAttributedString?
and made it a @Published property on an ObservableObject
-- that way, when it changes, the view gets notified right away.
The UIViewRepresentable
creates a label and updates it with the attributed string any time it changes.
In the event that you did want to try a more pure SwiftUI approach, this blog posts has some good resources for using NSAttributedString in SwiftUI (including the approach I took): https://swiftui-lab.com/attributed-strings-with-swiftui/
这篇关于SwiftUI中的Higlight语音发声的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!