Reputation: 3614
I have this app that use ObservedObject to share data across various views.
Defining the viewmodel
class MyViewModel: ObservableObject {
@Published var language: String?
}
Now for ContentView
struct ContentView: View {
@ObservedObject private var myViewModel = MyViewModel()
var body: some View {
Home()
.environmentObject(self.myViewModel)
}
}
Here is 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
here is used for debug purposes
clicking the button will set language to "American English" and the Text() will show the updated string.
Now put the app on background and then click the icon to call it back to foreground: despite nothing changed on the UI, myviewmodel is NIL.
To "restore" the state, I've modified ContentView to receive a "foreground notification", as suggested here 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"
}
}
}
The debug print in Home()'s onReceive works and shows the correct string, but the one in Text()
disappear, as if it receive the nil value and get no subsequent refresh.
Any idea?
EDIT Must keep IOS 13 compatibility
Upvotes: 2
Views: 1793
Reputation: 257789
Use instead StateObject
struct ContentView: View {
@StateObject private var myViewModel = MyViewModel()
...
Upvotes: 2