I am having problems getting ObservedObject to work. In this example I have a TabView with a Home and Settings tabs. On the Settings tab I have a button to toggle a bool to set if I purchased to remove ads or not.
The AdView text has an if condition, on an ObservedObject, but when I toggle the value the ad text doesn't go away / appear. If I close the app and re-launch, it updates correctly. How can I get this to update in realtime?
class Settings: ObservableObject {
@Published var purchasedRemoveAds: Bool {
didSet {
UserDefaults.standard.set(purchasedRemoveAds, forKey: "purchasedRemoveAds")
}
}
init() {
self.purchasedRemoveAds = UserDefaults.standard.bool(forKey: "purchasedRemoveAds")
}
}
struct ContentView: View {
@State var tabSelect: Int
@ObservedObject var settings: Settings
var body: some View {
TabView(selection: $tabSelect) {
NavigationView {
Home()
}
.tabItem {
Image(systemName: "house")
Text("Home")
}
.tag(0)
NavigationView {
SettingsView(settings: Settings())
}
.tabItem {
Image(systemName: "gearshape")
Text("Settings")
}
.tag(1)
}
//Show Ads at bottom of screen
if !settings.purchasedRemoveAds {
Text("AdView here").frame(height: 50).frame(maxWidth: .infinity).background(Color.green)
}
Spacer()
}
}
struct SettingsView: View {
@ObservedObject var settings: Settings
var body: some View {
List {
Section(header: Text("In-App Purchases")) {
Button {
settings.purchasedRemoveAds.toggle()
} label: {
Text("Remove Ads")
}
}.listRowBackground(Color.gray.opacity(0.1))
}
.navigationTitle("Settings")
}
}
On this line, you're creating a new instance of Settings
:
SettingsView(settings: Settings())
Because this instance of Settings
is instantiated before the switch is changed, it has no idea that the UserDefaults
have been adjusted.
Instead, pass the existing instance:
SettingsView(settings: settings)
Also, look into @AppStorage
where you can get some of this behavior for free from the system.