当 UserSettings 更改时,使用 Swift ObservableObject 更改视图标签

发布于 2025-01-21 00:31:05 字数 2451 浏览 4 评论 0原文

我在 Swift Playgrounds 中创建了一个小型示例项目来调试我遇到的问题。此示例项目包含一个主 ContentView,其中包含一个 Text 字段和一个在模式视图中打开“设置”的按钮。

当我打开“设置”并通过选择器更改设置时,我希望在我的 ContentView 中看到相应的 Text 标签更改。在当前项目中,我使用 @ObservableObject 类型别名来跟踪更改,我看到设置更改正确,但视图未更新。如果我在 Playgrounds 中重新启动预览,视图将使用更改后的设置进行更新。我希望 Text 标签能够实时更改。

代码如下:

ContentView.swift

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var userSettings = UserSettings()
    
    @State var isModal: Bool = false
    
    var body: some View {
        
        VStack {
            Text("Setting: " + userSettings.pickerSetting)
                .fontWeight(.semibold)
                .font(.title)
            Button(action: {
                    self.isModal = true
                }) {
                    Image(systemName: "gear")
                        .font(.title)
                }
                .padding()
                .foregroundColor(.white)
                .background(Color.gray)
                .cornerRadius(40)
                .sheet(isPresented: $isModal, content: {
                    UserSettingsView()
                })
                .environmentObject(userSettings)
        }
    }
}

UserSettings.swift

import Foundation

class UserSettings: ObservableObject {
    
    @Published var pickerSetting: String {
        didSet {
            UserDefaults.standard.set(pickerSetting, forKey: "pickerSetting")
        }
    }
    
    public var pickerSettings = ["Setting 1", "Setting 2", "Setting 3"]
    
    init() {
        self.pickerSetting = UserDefaults.standard.object(forKey: "pickerSetting") as? String ?? "Setting 1"
    }
}

UserSettingsView.swift

import SwiftUI

struct UserSettingsView: View {
    @ObservedObject var userSettings = UserSettings()
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("")) {
                    Picker(selection: $userSettings.pickerSetting, label: Text("Picker Setting")) {
                        ForEach(userSettings.pickerSettings, id: \.self) { setting in
                            Text(setting)
                        }
                    }
                }
            }
            .navigationBarTitle("Settings")
        }
    }
}

I’ve created a small sample project in Swift Playgrounds to debug an issue I’ve encountered. This sample project contains the a primary ContentView with a single Text field and a button that opens Settings in a modal view.

When I open Settings and change the a setting via a picker, I would like to see the corresponding Text label change in my ContentView. In the current project, I’m using the @ObservableObject Type Alias to track the change, and I see that the setting changes correctly, but the view is not updated. If I restart the preview in Playgrounds, the view is updated with the changed setting. I would expect the Text label to change in real-time.

The code is as follows:

ContentView.swift

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var userSettings = UserSettings()
    
    @State var isModal: Bool = false
    
    var body: some View {
        
        VStack {
            Text("Setting: " + userSettings.pickerSetting)
                .fontWeight(.semibold)
                .font(.title)
            Button(action: {
                    self.isModal = true
                }) {
                    Image(systemName: "gear")
                        .font(.title)
                }
                .padding()
                .foregroundColor(.white)
                .background(Color.gray)
                .cornerRadius(40)
                .sheet(isPresented: $isModal, content: {
                    UserSettingsView()
                })
                .environmentObject(userSettings)
        }
    }
}

UserSettings.swift

import Foundation

class UserSettings: ObservableObject {
    
    @Published var pickerSetting: String {
        didSet {
            UserDefaults.standard.set(pickerSetting, forKey: "pickerSetting")
        }
    }
    
    public var pickerSettings = ["Setting 1", "Setting 2", "Setting 3"]
    
    init() {
        self.pickerSetting = UserDefaults.standard.object(forKey: "pickerSetting") as? String ?? "Setting 1"
    }
}

UserSettingsView.swift

import SwiftUI

struct UserSettingsView: View {
    @ObservedObject var userSettings = UserSettings()
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("")) {
                    Picker(selection: $userSettings.pickerSetting, label: Text("Picker Setting")) {
                        ForEach(userSettings.pickerSettings, id: \.self) { setting in
                            Text(setting)
                        }
                    }
                }
            }
            .navigationBarTitle("Settings")
        }
    }
}

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

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

发布评论

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

评论(1

与之呼应 2025-01-28 00:31:05

发生这种情况是因为您创建了两个实例userettings。一个在contentViewuserettingsview中。

如果要继续使用.environmentObject(userettings)您需要使用@environmentobject var Userettings:userettingsview中的Usersettings

否则,您可以删除.environmentObject,并在userettingsview中使用@obseverObject

This happening because you have created two instances of UserSettings. One each in ContentView and UserSettingsView.

If you want to keep using .environmentObject(userSettings) the you need to use @EnvironmentObject var userSettings: UserSettings in UserSettingsView.

Otherwise you can drop the .environmentObject and use an @ObservedObject in UserSettingsView.

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