我有一个SwiftUI应用程序。它具有一个行列表,每个行都有一个常量属性,该属性表明是否需要将其打开,以及一个属性,其指示是否处于打开状态。仅当需要打开该行时,此第二个属性才可变。这些行已排序;需要开启的功能高于不需要开启的功能。还有一个“去!”按钮,当前已禁用。如果所有需要打开的行都已启用,我希望启用它,但是我不知道如何在视图层次结构中传递数据。我也不知道Combine,所以如果答案是正确的,那么示例将是不错的选择。谢谢!
import SwiftUI
struct ListView: View {
let models = [Model.testCase, .testCase2, .testCase3]
var body: some View {
NavigationView {
List(models.sorted { first, second in
if first.needsToBeOn { return true }
if !second.needsToBeOn { return true }
return false
}) { model in
NavigationLink(destination: EmptyView()) {
RowView(model: model)
}
}
.navigationBarTitle(Text("Models"))
.navigationBarItems(trailing: Button(action: {}) {
Text("Go!").font(.title)
}.disabled(true))
}
}
}
struct RowView: View {
let model: Model
@State var isOn = false
var body: some View {
HStack {
VStack {
Text("Must Be On:")
Text("\(model.needsToBeOn)")
}
Spacer()
VStack {
Text("Picked Up")
Toggle(isOn: $isOn) {
Text("")
}.labelsHidden().disabled(!model.needsToBeOn)
}
}.padding(7.5)
}
}
struct Model: Identifiable {
var id: UUID
let needsToBeOn: Bool
static let testCase = Model(id: UUID(), needsToBeOn: true)
static let testCase2 = Model(id: UUID(), needsToBeOn: true)
static let testCase3 = Model(id: UUID(), needsToBeOn: false)
}
答案 0 :(得分:0)
我没有机会测试,但请尝试以下代码
struct ListView: View {
@State private var models = [Model.testCase, .testCase2, .testCase3]
var body: some View {
NavigationView {
List(models.sorted { first, second in
if first.needsToBeOn { return true }
if !second.needsToBeOn { return true }
return false
}) { model in
NavigationLink(destination: EmptyView()) {
RowView(model: self.$model)
}
}
.navigationBarTitle(Text("Models"))
.navigationBarItems(trailing: Button(action: {}) {
Text("Go!").font(.title)
}.disabled(true))
}
}
}
struct RowView: View {
@Binding var model: Model
@State var isOn = false
var body: some View {
HStack {
VStack {
Text("Must Be On:")
Text("\(model.needsToBeOn)")
}
Spacer()
VStack {
Text("Picked Up")
Toggle(isOn: $isOn) {
Text("")
model.needsToBeOn = self.isOn
}.labelsHidden().disabled(!model.needsToBeOn)
}
}.padding(7.5)
}
}
答案 1 :(得分:0)
看起来像在工作。
struct ListView: View {
@State var models = [Model.testCase0, .testCase1, .testCase2, .testCase3]
var body: some View {
NavigationView {
List(models.enumerated().sorted { first, second in
first.element.needsToBeOn ? true : !second.element.needsToBeOn
}, id: \.element.id) { e in
NavigationLink(destination: EmptyView()) {
RowView(model: self.$models[e.offset])
}
}
.navigationBarTitle(Text("Models"))
.navigationBarItems(
leading:
Button(action: {
self.models.append(Model(needsToBeOn: true))
print(self.models.map{$0.needsToBeOn})
}) {
Text("Add")
},
trailing: Button(action: {}) {
Text("Go!").font(.title)
// optionally we filter to take only obligatory switches into account
}.disabled(!(models.filter({ $0.needsToBeOn}).reduce(true, { (r, m) in
r && m.needsToBeOn == m.isActuallyOn
}))))
}
}
}
struct RowView: View {
@Binding var model: Model
var body: some View {
HStack {
VStack {
Text("Must Be On:")
Text("\(model.needsToBeOn.description)")
}
Spacer()
VStack {
Text("Picked Up")
Toggle(isOn: $model.isActuallyOn) {
Text("")
}.labelsHidden().disabled(!model.needsToBeOn)
}
}.padding(7.5)
}
}
struct Model: Identifiable {
var id = UUID()
var needsToBeOn: Bool
var isActuallyOn: Bool = false
static let testCase0 = Model(needsToBeOn: false) // to check the sorting
static let testCase1 = Model(needsToBeOn: true)
static let testCase2 = Model(needsToBeOn: true)
static let testCase3 = Model(needsToBeOn: false)
}