我需要什么:我有一个步进器来设置值。如果用户使用不同单位的应用程序,该值完全不同。
问题是什么:当我只是在设置选项卡中使用单位选择器时,主选项卡中的值(在设置选项卡中存储为 @AppStorage)会正确更新。当我触摸步进器并修改主选项卡中的值时,如果我尝试修改设置选项卡中的单位,一切都会混乱! (虽然设置选项卡中的值不断正确更新,但主选项卡中显示的值却没有)。
设置选项卡: 班级
Defaults: ObservableObject {
@AppStorage("appUnits") var appUnits: String = "🇪🇺"
@AppStorage("memorizedDensity") var density: Double = 0.794
}
struct settings: View {
@ObservedObject var defaults = Defaults()
var body: some View {
List {
Section {
HStack {
ViewThatFits {
Text("App default Units")
}
Spacer(minLength: 10)
Picker(selection: $defaults.appUnits, label: Text("Unit")) {
ForEach(["🇪🇺", "🇺🇸"], id: \.self) {riga in
Text(riga)
}
}
.onChange(of: defaults.appUnits) {newValue in
if newValue == "🇪🇺" {
defaults.density = 0.793
} else if newValue == "🇺🇸" {
defaults.density = 6.66
}
// I need to set a different value when the unit changes
print(defaults.density)
}
.frame(width: 120)
.pickerStyle(.segmented)
}
}
}
}
}
主选项卡:
struct stepper: View {
@ObservedObject var defaults = Defaults()
var body: some View { fuelDatas }
var fuelDatas: some View {
VStack {
Text("Fuel density")
HStack {
Text(defaults.density, format: .number.precision(.fractionLength(defaults.appUnits == "🇪🇺" ? 3 : 2)))
Text(defaults.appUnits == "🇪🇺" ? "g/ml" : "lb/US gal")
}
Stepper("", value: defaults.$density, in: defaults.appUnits == "🇪🇺" ? 0.750...0.850 : 6...7, step: defaults.appUnits == "🇪🇺" ? 0.001 : 0.01)
.frame(width: 50.0)
}
}
}
我知道我弄乱了绑定的东西,并且我可能创建了两个事实来源,但我找不到代码中的问题! 这是示例项目-
理想情况下,您应该只在
@AppStorage
中声明 View
,而不是将它们包装在另一个 Defaults
类中。
struct stepper: View {
@AppStorage("appUnits") var appUnits: String = "🇪🇺"
@AppStorage("memorizedDensity") var density: Double = 0.794
...
}
如果出于某种原因你确实想要一个
Defaults
对象,你应该确保所有视图都使用相同的对象。
struct settings: View {
// do not initialise it here
@ObservedObject var defaults: Defaults
...
}
struct stepper: View {
// do not initialise it here
@ObservedObject var defaults: Defaults
...
}
在选项卡视图中,声明
@StateObject
并将其传递给步进器和设置。
@StateObject var defaults = Defaults()
var body: some View {
TabView {
NavigationStack {
stepper(defaults: defaults)
}
.tabItem { Label("stepper", systemImage: "1.circle") }
NavigationStack {
settings(defaults: defaults)
}
.tabItem { Label("setting", systemImage: "2.circle") }
}
}
您也可以将其作为
@EnvironmentObject
,
NavigationStack {
stepper()
}
.environmentObject(defaults)
...
struct stepper: View {
@EnvironmentObject var defaults: Defaults
...
}