首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI: UserDefaults绑定

SwiftUI: UserDefaults绑定
EN

Stack Overflow用户
提问于 2022-08-28 18:32:41
回答 1查看 118关注 0票数 1

我有一个设置视图,其中有一个按钮,用于切换存储在UserDefaults中的绑定。

代码语言:javascript
复制
struct Settings: View {
    @ObservedObject var settingsVM = SetttingsViewModel()

    var body: some View {
        if settingsVM.settingActivated {
            Text("Setting activated")
        } else {
            Text("Setting deactivated")
        }
        
        Button("Activate") {
            settingsVM.settingActivated.toggle()
        }
        

    }
    
}

SettingsViewModel

代码语言:javascript
复制
class SetttingsViewModel: ObservableObject {
    
    @Published  var settingActivated: Bool = UserDefaults.standard.bool(forKey: "settingActivated") {
    didSet {
        UserDefaults.standard.set(self.settingActivated, forKey: "settingActivated")
      }
    }
    
}

当我按下按钮时,设置视图中的文本(“设置激活/禁用”)会立即更新,但是ContentView中的文本不会改变,除非我重新启动应用程序&我不知道为什么。

代码语言:javascript
复制
struct ContentView: View {
    @ObservedObject var settingsVM = SetttingsViewModel()
    @State private var showsettings = false
    var body: some View {
        
        if settingsVM.settingActivated {
            
            Text("Setting Activated")
                .padding(.top)
        } else {
            Text("Setting Deactivated")
                .padding(.top)
        }
            Button("Show Settings") {
                showsettings.toggle()
                
            }
            .sheet(isPresented: $showsettings) {
                Settings()
                   }
            .frame(width: 300, height: 300)
       }
    }

这是一个macOS 10.15应用程序,所以我不能使用@AppStorage

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-28 18:39:55

现在,您在视图模型中没有任何代码来对UserDefaults中的更改作出反应。也就是说,如果UserDefaults得到了一个新的值集,它就不会知道它了。而且,由于您在两个不同的视图中使用不同的SettingsViewModel实例,它们很容易变得不同步。

最简单的更改是将相同的SettingsViewModel实例传递给Settings

代码语言:javascript
复制
struct Settings: View {
    @ObservedObject var settingsVM: SettingsViewModel //<-- Here

    var body: some View {
        if settingsVM.settingActivated {
            Text("Setting activated")
        } else {
            Text("Setting deactivated")
        }
        
        Button("Activate") {
            settingsVM.settingActivated.toggle()
        }
    }
}

struct ContentView: View {
    @ObservedObject var settingsVM = SetttingsViewModel()
    @State private var showsettings = false
    var body: some View {
        
        if settingsVM.settingActivated {
            
            Text("Setting Activated")
                .padding(.top)
        } else {
            Text("Setting Deactivated")
                .padding(.top)
        }
            Button("Show Settings") {
                showsettings.toggle()
                
            }
            .sheet(isPresented: $showsettings) {
                Settings(settingsVM: settingsVM) //<-- Here
            }
            .frame(width: 300, height: 300)
       }
    }

另一种选择是使用自定义属性包装器(如AppStorage,但可用于早期目标):https://xavierlowmiller.github.io/blog/2020/09/04/iOS-13-AppStorage

此外,@vadian的评论也很重要--如果您可以访问它,您可能希望使用@StateObject。但是,由于您没有,重要的是将您的ObservableObject存储在顶层,这样它就不会被重新创建。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73521244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档