当 UserSettings 更改时,使用 Swift ObservableObject 更改视图标签
我在 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
发生这种情况是因为您创建了两个实例
userettings
。一个在contentView
和userettingsview
中。如果要继续使用
.environmentObject(userettings)
您需要使用@environmentobject var Userettings:
。userettingsview
中的Usersettings否则,您可以删除
.environmentObject
,并在userettingsview
中使用@obseverObject
。This happening because you have created two instances of
UserSettings
. One each inContentView
andUserSettingsView
.If you want to keep using
.environmentObject(userSettings)
the you need to use@EnvironmentObject var userSettings: UserSettings
inUserSettingsView
.Otherwise you can drop the
.environmentObject
and use an@ObservedObject
inUserSettingsView
.