Лучший способ отобразить список переключаемых массивов элементов в SwiftUI - PullRequest
0 голосов
/ 15 февраля 2020

Для чего-то, что было бы просто с 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 в качестве параметра.

Follow этот ответ , моя следующая попытка была ...

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, которое устанавливается при выборе ЛЮБОГО из его измерений, что может сообщить ваш ответ

1 Ответ

0 голосов
/ 15 февраля 2020

использование 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**

...