SwiftUI中的Higlight语音发声 [英] Higlight speech utterance in SwiftUI

查看:124
本文介绍了SwiftUI中的Higlight语音发声的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆