如何从自定义代表类内部的回调中更新视图?

发布于 2025-01-18 10:39:43 字数 6227 浏览 1 评论 0原文

我正在开发一个基督教应用程序,一切都很顺利,除了一件事:我无法解决如何让标签在我的 AVSpeechSynthesizer 讲完后更新其文本。

例如,读完祈祷文后,文本应再次更新为“播放”。它在所有其他已知场景中都能正确执行此操作(暂停工作、恢复工作、停止工作、重新启动工作等,如标签中相应更新所示)。

请在这里查看我的代码:

import SwiftUI
import AVFoundation

class GlobalVarsModel: ObservableObject {
    @Published var prayerAudioID: UUID?
    @Published var uttPrayerAudio = ""
    @Published var strAudioBtnImgStr = "play.fill"
    @Published var strAudioBtnText = "Play Audio"
    static let audioSession = AVAudioSession.sharedInstance()
    static var synthesizer = CustomAVSpeechSynth()
}

class CustomAVSpeechSynth: AVSpeechSynthesizer, AVSpeechSynthesizerDelegate {
    
    //NOT DESIRED OUTPUT LIST
    //@Published
    //@ObservedObject
    //@State
    
    @StateObject var gVars = GlobalVarsModel()
    
    override init() {
        super.init()
        delegate = self
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        print("Finished praying.")
        print(gVars.strAudioBtnText)
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
    }
}

struct TappedPrayerView: View {
    public var tappedPrayer: Prayer
    @StateObject public var gVars = GlobalVarsModel()
    @Environment(\.scenePhase) var scenePhase
    
    var body: some View {
        ScrollView {
            VStack {
                Text(tappedPrayer.strTitle).font(.title2).padding()
                HStack {
                    Spacer()
                    Button {
                        gVars.prayerAudioID = tappedPrayer.id
                        gVars.uttPrayerAudio = tappedPrayer.strText
                        
                        if (gVars.strAudioBtnText == "Play Audio") {
                            gVars.strAudioBtnImgStr = "pause.fill"
                            gVars.strAudioBtnText = "Pause Audio"
                            if (GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) {
                                GlobalVarsModel.synthesizer.stopSpeaking(at: .immediate)
                                GlobalVarsModel.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            } else {
                                GlobalVarsModel.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            }
                        } else if (gVars.strAudioBtnText == "Pause Audio") {
                            GlobalVarsModel.synthesizer.pauseSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Continue Audio"
                        } else if (gVars.strAudioBtnText == "Continue Audio") {
                            if (GlobalVarsModel.synthesizer.isPaused) {
                                GlobalVarsModel.synthesizer.continueSpeaking()
                                gVars.strAudioBtnImgStr = "pause.fill"
                                gVars.strAudioBtnText = "Pause Audio"
                            }
                        }
                    } label: {
                        Label(gVars.strAudioBtnText, systemImage: gVars.strAudioBtnImgStr).font(.title3).padding()
                    }.onAppear {
                        if ((GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) && tappedPrayer.id != gVars.prayerAudioID) {
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                        }
                    }
                    Spacer()
                    Button {
                        if (GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) {
                            GlobalVarsModel.synthesizer.stopSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                            gVars.prayerAudioID = UUID(uuidString: String(Int.random(in: 0..<7)) + (gVars.prayerAudioID?.uuidString ?? "777"))
                        }
                    } label: {
                        Label("Restart", systemImage: "restart.circle.fill").font(.title3).padding()
                    }
                    Spacer()
                }
                Spacer()
                Text(tappedPrayer.strText).padding()
                Spacer()
            }
        }.onAppear {
            if (GlobalVarsModel.synthesizer.isPaused) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "play.fill"
                    gVars.strAudioBtnText = "Continue Audio"
                }
            } else if (GlobalVarsModel.synthesizer.isSpeaking) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "pause.fill"
                    gVars.strAudioBtnText = "Pause Audio"
                }
            } else {
                gVars.strAudioBtnImgStr = "play.fill"
                gVars.strAudioBtnText = "Play Audio"
            }
        }.onChange(of: scenePhase) { newPhase in
            if (newPhase == .active) {
            } else if (newPhase == .inactive) {
            } else if (newPhase == .background) {
            }
        }
    }
    
    struct TappedPrayerView_Previews: PreviewProvider {
        static var previews: some View {
            let defaultPrayer = Prayer(strTitle: "Default title", strText: "Default text")
            TappedPrayerView(tappedPrayer: defaultPrayer)
        }
    }
}

I am working on a Christian app, all is going well, except for 1 thing: I can't solve how to get the label to update its text after my AVSpeechSynthesizer has finished speaking.

For example, after the prayer has finished being read, the text should update to "Play" again. It does this correctly in all other known scenarios (Pause works, Resume works, stop works, restart works, etc. as in the label updates accordingly).

Please see my code here:

import SwiftUI
import AVFoundation

class GlobalVarsModel: ObservableObject {
    @Published var prayerAudioID: UUID?
    @Published var uttPrayerAudio = ""
    @Published var strAudioBtnImgStr = "play.fill"
    @Published var strAudioBtnText = "Play Audio"
    static let audioSession = AVAudioSession.sharedInstance()
    static var synthesizer = CustomAVSpeechSynth()
}

class CustomAVSpeechSynth: AVSpeechSynthesizer, AVSpeechSynthesizerDelegate {
    
    //NOT DESIRED OUTPUT LIST
    //@Published
    //@ObservedObject
    //@State
    
    @StateObject var gVars = GlobalVarsModel()
    
    override init() {
        super.init()
        delegate = self
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        print("Finished praying.")
        print(gVars.strAudioBtnText)
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
    }
}

struct TappedPrayerView: View {
    public var tappedPrayer: Prayer
    @StateObject public var gVars = GlobalVarsModel()
    @Environment(\.scenePhase) var scenePhase
    
    var body: some View {
        ScrollView {
            VStack {
                Text(tappedPrayer.strTitle).font(.title2).padding()
                HStack {
                    Spacer()
                    Button {
                        gVars.prayerAudioID = tappedPrayer.id
                        gVars.uttPrayerAudio = tappedPrayer.strText
                        
                        if (gVars.strAudioBtnText == "Play Audio") {
                            gVars.strAudioBtnImgStr = "pause.fill"
                            gVars.strAudioBtnText = "Pause Audio"
                            if (GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) {
                                GlobalVarsModel.synthesizer.stopSpeaking(at: .immediate)
                                GlobalVarsModel.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            } else {
                                GlobalVarsModel.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            }
                        } else if (gVars.strAudioBtnText == "Pause Audio") {
                            GlobalVarsModel.synthesizer.pauseSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Continue Audio"
                        } else if (gVars.strAudioBtnText == "Continue Audio") {
                            if (GlobalVarsModel.synthesizer.isPaused) {
                                GlobalVarsModel.synthesizer.continueSpeaking()
                                gVars.strAudioBtnImgStr = "pause.fill"
                                gVars.strAudioBtnText = "Pause Audio"
                            }
                        }
                    } label: {
                        Label(gVars.strAudioBtnText, systemImage: gVars.strAudioBtnImgStr).font(.title3).padding()
                    }.onAppear {
                        if ((GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) && tappedPrayer.id != gVars.prayerAudioID) {
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                        }
                    }
                    Spacer()
                    Button {
                        if (GlobalVarsModel.synthesizer.isSpeaking || GlobalVarsModel.synthesizer.isPaused) {
                            GlobalVarsModel.synthesizer.stopSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                            gVars.prayerAudioID = UUID(uuidString: String(Int.random(in: 0..<7)) + (gVars.prayerAudioID?.uuidString ?? "777"))
                        }
                    } label: {
                        Label("Restart", systemImage: "restart.circle.fill").font(.title3).padding()
                    }
                    Spacer()
                }
                Spacer()
                Text(tappedPrayer.strText).padding()
                Spacer()
            }
        }.onAppear {
            if (GlobalVarsModel.synthesizer.isPaused) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "play.fill"
                    gVars.strAudioBtnText = "Continue Audio"
                }
            } else if (GlobalVarsModel.synthesizer.isSpeaking) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "pause.fill"
                    gVars.strAudioBtnText = "Pause Audio"
                }
            } else {
                gVars.strAudioBtnImgStr = "play.fill"
                gVars.strAudioBtnText = "Play Audio"
            }
        }.onChange(of: scenePhase) { newPhase in
            if (newPhase == .active) {
            } else if (newPhase == .inactive) {
            } else if (newPhase == .background) {
            }
        }
    }
    
    struct TappedPrayerView_Previews: PreviewProvider {
        static var previews: some View {
            let defaultPrayer = Prayer(strTitle: "Default title", strText: "Default text")
            TappedPrayerView(tappedPrayer: defaultPrayer)
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

老子叫无熙 2025-01-25 10:39:43

您的代码多个问题。

  1. 您正在初始化GlobalVarsModel两次。一旦看见,一次就在代表中。因此,一个不会反映出另一个变化。

  2. 您正在以avspeechsynthesizer的子类实现代表因此,它在其中倾斜,并且在发生事件时可以更新视图。

我将实现更改为解决此问题:


class GlobalVarsViewmodel: NSObject, ObservableObject { //You need to derive from NSObject first, because `AVSpeechSynthesizer` is `objc` related
    @Published var prayerAudioID: UUID?
    @Published var uttPrayerAudio = ""
    @Published var strAudioBtnImgStr = "play.fill"
    @Published var strAudioBtnText = "Play Audio"
    let audioSession = AVAudioSession.sharedInstance()
    var synthesizer = CustomAVSpeechSynth()
    
    override init(){
        super.init()
        synthesizer.delegate = self // assign the delegate
    }
}

extension GlobalVarsViewmodel: AVSpeechSynthesizerDelegate{ // extend the viewmodel to implement the delegate
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        print("Finished praying.")
        strAudioBtnImgStr = "play.fill" // here assign the text and button appearance
        strAudioBtnText = "Play Audio"
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
    }
}
// I don´t think you need this anymore
class CustomAVSpeechSynth: AVSpeechSynthesizer {
    
    //NOT DESIRED OUTPUT LIST
    //@Published
    //@ObservedObject
    //@State
}

struct TappedPrayerView: View {
    var tappedPrayer: Prayer
    @StateObject private var gVars = GlobalVarsViewmodel()
    @Environment(\.scenePhase) var scenePhase
    
    var body: some View {
        ScrollView {
            VStack {
                Text(tappedPrayer.strTitle).font(.title2).padding()
                HStack {
                    Spacer()
                    Button {
                        gVars.prayerAudioID = tappedPrayer.id
                        gVars.uttPrayerAudio = tappedPrayer.strText
                        
                        if (gVars.strAudioBtnText == "Play Audio") {
                            gVars.strAudioBtnImgStr = "pause.fill"
                            gVars.strAudioBtnText = "Pause Audio"
                            if (gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) {
                                gVars.synthesizer.stopSpeaking(at: .immediate)
                                gVars.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            } else {
                                gVars.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            }
                        } else if (gVars.strAudioBtnText == "Pause Audio") {
                            gVars.synthesizer.pauseSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Continue Audio"
                        } else if (gVars.strAudioBtnText == "Continue Audio") {
                            if (gVars.synthesizer.isPaused) {
                                gVars.synthesizer.continueSpeaking()
                                gVars.strAudioBtnImgStr = "pause.fill"
                                gVars.strAudioBtnText = "Pause Audio"
                            }
                        }
                    } label: {
                        Label(gVars.strAudioBtnText, systemImage: gVars.strAudioBtnImgStr).font(.title3).padding()
                    }.onAppear {
                        if ((gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) && tappedPrayer.id != gVars.prayerAudioID) {
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                        }
                    }
                    Spacer()
                    Button {
                        if (gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) {
                            gVars.synthesizer.stopSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                            gVars.prayerAudioID = UUID(uuidString: String(Int.random(in: 0..<7)) + (gVars.prayerAudioID?.uuidString ?? "777"))
                        }
                    } label: {
                        Label("Restart", systemImage: "restart.circle.fill").font(.title3).padding()
                    }
                    Spacer()
                }
                Spacer()
                Text(tappedPrayer.strText).padding()
                Spacer()
            }
        }.onAppear {
            if (gVars.synthesizer.isPaused) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "play.fill"
                    gVars.strAudioBtnText = "Continue Audio"
                }
            } else if (gVars.synthesizer.isSpeaking) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "pause.fill"
                    gVars.strAudioBtnText = "Pause Audio"
                }
            } else {
                gVars.strAudioBtnImgStr = "play.fill"
                gVars.strAudioBtnText = "Play Audio"
            }
        }.onChange(of: scenePhase) { newPhase in
            if (newPhase == .active) {
            } else if (newPhase == .inactive) {
            } else if (newPhase == .background) {
            }
        }
    }
    
    struct TappedPrayerView_Previews: PreviewProvider {
        static var previews: some View {
            let defaultPrayer = Prayer(strTitle: "Default title", strText: "Default text")
            TappedPrayerView(tappedPrayer: defaultPrayer)
        }
    }
}

备注:

  • 我将globalVarsModel的名称更改为globalvarsviewModel,因为正是这样,即ViewModel。
  • 我将合成器var更改为实例相关,而不是静态的
  • avauioSession

编辑以添加评论以澄清:
我从静态更改了实现,因为这里不需要。您可以在这里阅读更多有关它的信息 - &gt; https://www.donnywals.com/fectife - 使用静态和类别的方法/

Multiple issues with your code.

  1. You are initializing GlobalVarsModel twice. Once in the View and once in the delegate. So changes in one won´t reflect in the other.

  2. You are implementing the delegate in a subclass of your AVSpeechSynthesizer therefor it is capsulated in it and you can´t update your View when an event arises.

I changed the implementation to address this issues:


class GlobalVarsViewmodel: NSObject, ObservableObject { //You need to derive from NSObject first, because `AVSpeechSynthesizer` is `objc` related
    @Published var prayerAudioID: UUID?
    @Published var uttPrayerAudio = ""
    @Published var strAudioBtnImgStr = "play.fill"
    @Published var strAudioBtnText = "Play Audio"
    let audioSession = AVAudioSession.sharedInstance()
    var synthesizer = CustomAVSpeechSynth()
    
    override init(){
        super.init()
        synthesizer.delegate = self // assign the delegate
    }
}

extension GlobalVarsViewmodel: AVSpeechSynthesizerDelegate{ // extend the viewmodel to implement the delegate
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        print("Finished praying.")
        strAudioBtnImgStr = "play.fill" // here assign the text and button appearance
        strAudioBtnText = "Play Audio"
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
    }
}
// I don´t think you need this anymore
class CustomAVSpeechSynth: AVSpeechSynthesizer {
    
    //NOT DESIRED OUTPUT LIST
    //@Published
    //@ObservedObject
    //@State
}

struct TappedPrayerView: View {
    var tappedPrayer: Prayer
    @StateObject private var gVars = GlobalVarsViewmodel()
    @Environment(\.scenePhase) var scenePhase
    
    var body: some View {
        ScrollView {
            VStack {
                Text(tappedPrayer.strTitle).font(.title2).padding()
                HStack {
                    Spacer()
                    Button {
                        gVars.prayerAudioID = tappedPrayer.id
                        gVars.uttPrayerAudio = tappedPrayer.strText
                        
                        if (gVars.strAudioBtnText == "Play Audio") {
                            gVars.strAudioBtnImgStr = "pause.fill"
                            gVars.strAudioBtnText = "Pause Audio"
                            if (gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) {
                                gVars.synthesizer.stopSpeaking(at: .immediate)
                                gVars.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            } else {
                                gVars.synthesizer.speak(AVSpeechUtterance(string: gVars.uttPrayerAudio))
                            }
                        } else if (gVars.strAudioBtnText == "Pause Audio") {
                            gVars.synthesizer.pauseSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Continue Audio"
                        } else if (gVars.strAudioBtnText == "Continue Audio") {
                            if (gVars.synthesizer.isPaused) {
                                gVars.synthesizer.continueSpeaking()
                                gVars.strAudioBtnImgStr = "pause.fill"
                                gVars.strAudioBtnText = "Pause Audio"
                            }
                        }
                    } label: {
                        Label(gVars.strAudioBtnText, systemImage: gVars.strAudioBtnImgStr).font(.title3).padding()
                    }.onAppear {
                        if ((gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) && tappedPrayer.id != gVars.prayerAudioID) {
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                        }
                    }
                    Spacer()
                    Button {
                        if (gVars.synthesizer.isSpeaking || gVars.synthesizer.isPaused) {
                            gVars.synthesizer.stopSpeaking(at: .immediate)
                            gVars.strAudioBtnImgStr = "play.fill"
                            gVars.strAudioBtnText = "Play Audio"
                            gVars.prayerAudioID = UUID(uuidString: String(Int.random(in: 0..<7)) + (gVars.prayerAudioID?.uuidString ?? "777"))
                        }
                    } label: {
                        Label("Restart", systemImage: "restart.circle.fill").font(.title3).padding()
                    }
                    Spacer()
                }
                Spacer()
                Text(tappedPrayer.strText).padding()
                Spacer()
            }
        }.onAppear {
            if (gVars.synthesizer.isPaused) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "play.fill"
                    gVars.strAudioBtnText = "Continue Audio"
                }
            } else if (gVars.synthesizer.isSpeaking) {
                if (tappedPrayer.id == gVars.prayerAudioID) {
                    gVars.strAudioBtnImgStr = "pause.fill"
                    gVars.strAudioBtnText = "Pause Audio"
                }
            } else {
                gVars.strAudioBtnImgStr = "play.fill"
                gVars.strAudioBtnText = "Play Audio"
            }
        }.onChange(of: scenePhase) { newPhase in
            if (newPhase == .active) {
            } else if (newPhase == .inactive) {
            } else if (newPhase == .background) {
            }
        }
    }
    
    struct TappedPrayerView_Previews: PreviewProvider {
        static var previews: some View {
            let defaultPrayer = Prayer(strTitle: "Default title", strText: "Default text")
            TappedPrayerView(tappedPrayer: defaultPrayer)
        }
    }
}

Remarks:

  • I changed the name of GlobalVarsModel to GlobalVarsViewmodel because it is exactly that, a Viewmodel.
  • I changed the synthesizer var to be instance related instead of static
  • same for the AVAudioSession

Edit to adress the comment for clarification:
I changed the implementation from static because it is not needed here. You can read more about it here -> https://www.donnywals.com/effectively-using-static-and-class-methods-and-properties/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文