如何将字典的值绑定到 SwiftUI 控件?

Jac*_*ger 3 binding dictionary list swift swiftui

我有class DataPoint一个字典的值。

DataPoint有一个value我需要绑定到SliderSwiftUI 中的成员变量。

我公司提供的数据class AppData作为@Environment Object对SwiftUI,字典持有的实例class DataPoint

我无法将DataPoint.value成员变量绑定到 SwiftUISlider值。

这些是相关的代码片段。

@Published 数据:

class AppData: ObservableObject {
    @Published var dataPoints: [UUID : DataPoint] = [:] {
    ...
}
Run Code Online (Sandbox Code Playgroud)

数据结构:

class DataPoint: Identifiable {
    var id = UUID()
    var value: Double
}
Run Code Online (Sandbox Code Playgroud)

DataPoints 的 SwiftUI 视图AppDataList

struct AppDataList: View {
    @EnvironmentObject var appData: AppData

    var body: some View {
        NavigationView {
            List(Array(appData.dataPoints.values)) { dataPoint in
                NavigationLink(destination: DataPointDetail(dataPointID: dataPoint.id)) {
                    Text("\(dataPoint.value)")
                }
            }
    ...
}
Run Code Online (Sandbox Code Playgroud)

DataPointDetail我挣扎的 SwiftUI视图,它引用自AppDataList

struct DataPointDetail: View {
    @EnvironmentObject var appData: AppData
    var dataPointID: UUID

    var body: some View {
        HStack(alignment: .top) {
            VStack(alignment: .leading) {
                Text("Data Point Detail")
                Text("\(appData.dataPoints[dataPointID]!.value)")
/* This line */
/* troubles  */
/* me!       */
/*  --->     */ Slider(value: appData.dataPoints[dataPointID]?.value, in: 0...10000)
                Spacer()
                Text("\(appData.dataPoints[dataPointID]!.id)")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根内容视图:

struct ContentView: View {
    @EnvironmentObject var appData: AppData

    var body: some View {
        VStack {
            if appData.dataPoints.count > 0 {
                AppDataList()
            } else {
                NoDataPoints()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在 SceneDelegate 中创建根内容视图:

        let contentView = ContentView()
            .environmentObject(appData)
Run Code Online (Sandbox Code Playgroud)

我在编辑器中收到一个错误:Static member 'leading' cannot be used on instance of type 'HorizontalAlignment'它在 DataPointDetail 视图中的 VStack 行中。我相信它与 VStack 无关。

静态成员 'leading' 不能用于类型 'Horizo​​ntalAlignment' 的实例

注释掉该Slider行会生成可编译和可运行的代码。

怎样才能做到这一点?

Asp*_*eri 7

最快速的解决方案是使用包装器绑定,如下面的快照

Slider(value: Binding<Double>(
    get: { self.appData.dataPoints[self.dataPointID]?.value ?? 0 },
    set: { self.appData.dataPoints[self.dataPointID]?.value = $0}), in: 0...10000)
Run Code Online (Sandbox Code Playgroud)