Проблема с вашим кодом на данный момент заключается в том, что даже если вы наблюдаете изменения в measurements
, они не будут обновляться при обновлении выбора, потому что вы объявили var isSelected: Binding<Bool>
как привязку. Это означает, что SwiftUI хранит его вне вашей структуры, а сама структура не обновляется (остается неизменной).
Вместо этого вы можете вместо этого объявить @Published var selectedMeasurementId: UUID? = nil
в вашей модели, поэтому ваш код будет чем-то как это:
import SwiftUI
import Combine
struct NextView: View {
var body: some View {
Text("Next View")
}
}
struct MeasurementsView: View {
@ObservedObject var model: Model
var body: some View {
let hasSelection = Binding<Bool> (
get: {
self.model.selectedMeasurementId != nil
},
set: { value in
self.model.selectedMeasurementId = nil
}
)
return NavigationView {
List(model.measurements) { measurement in
MeasurementView(measurement: measurement, selectedMeasurementId: self.$model.selectedMeasurementId)
}
.navigationBarTitle("Select Measurements")
.navigationBarItems(trailing: NavigationLink(destination: NextView(), isActive: hasSelection, label: {
Text("Next")
}))
}
}
}
struct MeasurementView: View {
let measurement: Model.Measurement
@Binding var selectedMeasurementId: UUID?
var body: some View {
let isSelected = Binding<Bool>(
get: {
self.selectedMeasurementId == self.measurement.id
},
set: { value in
if value {
self.selectedMeasurementId = self.measurement.id
} else {
self.selectedMeasurementId = nil
}
}
)
return HStack {
Text(measurement.name)
.font(.subheadline)
Spacer()
Toggle(measurement.name, isOn: isSelected)
.labelsHidden()
}
}
}
final class Model: ObservableObject {
@Published var selectedMeasurementId: UUID? = nil
struct Measurement: Identifiable {
var id = UUID()
let name: String
init(name: String) {
self.name = name
}
}
@Published var measurements: [Measurement]
init(measurements: [Measurement]) {
self.measurements = measurements
}
}
Я не совсем уверен, как вы хотите, чтобы навигационная кнопка на панели навигации работала. Сейчас я просто установил выбор на ноль, когда он нажал. Вы можете изменить его в зависимости от того, что вы хотите сделать.
Если вы хотите поддерживать множественный выбор, вы можете вместо этого использовать набор выбранных идентификаторов.
Кроме того, похоже на iOS Симулятор имеет некоторые проблемы с навигацией, но я тестировал на физическом устройстве, и он работал.