在SwiftUI中显示项目的可切换数组列表的最佳方法

时间:2020-02-15 14:39:10

标签: swiftui swiftui-list

对于UIKit来说很简单的事情,我正在努力寻找使用SwiftUI的最佳解决方案。我将不胜感激。

我有一个对象数组,可以选择每个对象。我的第一次尝试显示的是:

final class MeasurementSelections: ObservableObject {

    struct Measurement: Identifiable {
        let id = UUID()
        let name: String
        var isSelected: Bool = false

        init(name: String) {
            self.name = name
        }
    }

    @Published var measurements: [Measurement]

    init(measurements: [Measurement]) {
        self.measurements = measurements
    }
}

struct Readings: View {

    @ObservedObject var model: MeasurementSelections

    var body: some View {
        List(0..<model.measurements.count) { index in
            Text(self.model.measurements[index].name)
                .font(.subheadline)
            Spacer()
            Toggle(self.model.measurements[index].name, isOn: self.$model.measurements[index].isSelected)
                .labelsHidden()
        }
    }
}

这是相当简单的,但是使用Range和复制self.model.measurements[index]似乎并不正确……我宁愿有一个单独的View以Measurement作为参数。

跟随this answer,我的下一个尝试是……

final class MeasurementSelections: ObservableObject {

    struct Measurement: Identifiable {
        let id = UUID()
        let name: String
        var isSelected: Binding<Bool>

        private var selected: Bool = false

        init(name: String) {
            self.name = name

            let selected = CurrentValueSubject<Bool, Never>(false)
            self.isSelected = Binding<Bool>(get: { selected.value }, set: { selected.value = $0 })
        }
    }

    @Published var measurements: [Measurement]

    init(measurements: [Measurement]) {
        self.measurements = measurements
    }
}

struct Readings: View {

    @ObservedObject var model: MeasurementSelections

    var body: some View {
        VStack {
            MeasurementView(measurement: measurement)
        }
    }
}

struct MeasurementView: View {
    let measurement: MeasurementSelections.Measurement
    var body: some View {
        HStack {
            Text(measurement.name)
                .font(.subheadline)
            Spacer()
            Toggle(measurement.name, isOn: measurement.isSelected)
                .labelsHidden()
        }
    }
}

关于视图分离,这更好,但是现在MeasurementSelections类已经变得更加复杂,并且需要Combine。

这个问题是否有解决方案,可以保持视图分离但模型更简单?

另外,我最终希望MeasurementSelections公开一个可绑定(?)Bool属性,该属性在选择任何度量时都会设置,这可能会告诉您答案

1 个答案:

答案 0 :(得分:-1)

Range的使用和复制 self.model.measurements [index]似乎不正确……

没有复制,您直接在模型中操作数据,而无需任何“复制”

import SwiftUI

struct Data: Identifiable {
    let id = UUID()
    var name: String
    var on_off: Bool
}

class Model: ObservableObject {
    @Published var data = [Data(name: "alfa", on_off: false), Data(name: "beta", on_off: false), Data(name: "gama", on_off: false)]
}



struct ContentView: View {
    @ObservedObject var model = Model()
    var body: some View {
        List(0 ..< model.data.count) { idx in
            HStack {
                Text(verbatim: self.model.data[idx].name)
                Toggle(isOn: self.$model.data[idx].on_off) {
                    EmptyView()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

**enter image description here**