SwiftUI:步进器干扰绑定变量

问题描述 投票:0回答:1

我需要什么:我有一个步进器来设置值。如果用户使用不同单位的应用程序,该值完全不同。

问题是什么:当我只是在设置选项卡中使用单位选择器时,主选项卡中的值(在设置选项卡中存储为 @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)
        }
    }
}

我知道我弄乱了绑定的东西,并且我可能创建了两个事实来源,但我找不到代码中的问题! 这是示例项目-

swiftui binding picker stepper
1个回答
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

    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.