【问题标题】:Best way to display a list of toggleable array of items in SwiftUI在 SwiftUI 中显示可切换的项目列表的最佳方式
【发布时间】:2020-02-15 14:39:10
【问题描述】:

对于使用 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] 似乎不正确……我宁愿有一个单独的视图,它以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 类变得更加复杂,并且需要合并。

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

此外,我最终希望 MeasurementSelections 公开一个可绑定的 (?) Bool 属性,该属性在选择其任何测量值时设置,这可能会告知您的答案

【问题讨论】:

    标签: swiftui swiftui-list


    【解决方案1】:

    范围的使用和复制 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()
        }
    }
    

    【讨论】:

    • 这和我的第一个例子没有什么不同。
    • 对,没区别,用吧!没有复制,这是最直接的方法。最好的是,它是完全声明式 (SwiftUI) 方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2018-08-17
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多