iOS Swiftui App 返回前台重置 ObservedObjects

Posted

技术标签:

【中文标题】iOS Swiftui App 返回前台重置 ObservedObjects【英文标题】:iOS Swiftui App returning to foreground reset ObservedObjects 【发布时间】:2021-04-26 14:38:29 【问题描述】:

我有这个应用程序,它使用 ObservedObject 在各种视图之间共享数据。

定义视图模型

class MyViewModel: ObservableObject 
    @Published var language: String?

现在是内容视图

struct ContentView: View 
    @ObservedObject private var myViewModel = MyViewModel()

    var body: some View 
        Home()
        .environmentObject(self.myViewModel)
    

这里是 Home()

struct Home: View 
    @EnvironmentObject var myViewModel: MyViewModel

    var body: some View 
        VStack 
            Text(self.myViewModel.language ?? "")
                .onReceive(self.myViewModel.$language, perform:  language in
                    print(language)
                )
            Button(action: 
                self.myViewModel.language = "American English"
            , label: 
                Text("Set the language")
            )
        
    

onReceive 这里用于调试目的

点击按钮会将语言设置为“美式英语”,Text() 将显示更新后的字符串。

现在将应用置于后台,然后单击图标将其调回前台:尽管 UI 上没有任何更改,但 myviewmodel 为 NIL。

为了“恢复”状态,我修改了 ContentView 以接收“前台通知”,如此处所建议的 https://www.hackingwithswift.com/books/ios-swiftui/how-to-be-notified-when-your-swiftui-app-moves-to-the-background

struct ContentView: View 
    @ObservedObject private var myViewModel = MyViewModel()

    var body: some View 
        Home()
        .environmentObject(self.myViewModel)
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification))  _ in
           self.myViewModel.language = "American English"
        
    

Home() 的 onReceive 中的调试打印工作并显示正确的字符串,但 Text() 中的那个消失了,好像它收到了 nil 值并且没有后续刷新。

有什么想法吗?

编辑 必须保持 IOS 13 兼容性

【问题讨论】:

【参考方案1】:

改用StateObject

struct ContentView: View 
    @StateObject private var myViewModel = MyViewModel()

...

【讨论】:

我是个白痴,忘了说我需要保持 IOS 13 的兼容性。也编辑了问题。对不起@asperi 然后在ContentView 之外创建MyViewModel() 并将其注入,例如AppDelegate,等等。实际上没有人说 ContentView 只创建一次,所以一旦重新创建(在你的情况下,放在前台)你就有了 MyViewModel 的新实例。 我刚刚就如何在 scenedelegate 上设置它进行了一些斗争,但这似乎是答案。 @asperi 您能否添加一个答案(或编辑这个答案)以便给您应得的荣誉?

以上是关于iOS Swiftui App 返回前台重置 ObservedObjects的主要内容,如果未能解决你的问题,请参考以下文章

返回前台时导航栏位置重置

iOS 14.0 之后如何解决 SwiftUI 中 RealmSwift.App 和 SwiftUI.App 的冲突?

02. 将异常堆栈信息,返回给前台,便于排查问题.

swiftUI中用Xcode创建Mac OS app项目和iOS app项目的区别?

ios-APP后台切前台token处理

iOS SwiftUI App Clip WKWebView 和 SFSafariViewController 不起作用