SwiftUI从列表向上传递数据视图层次结构
我有一个SwiftUI应用程序。它有一个行列表,每个行都有一个常量属性表示它是否需要打开,还有一个属性表示它是否打开。第二个属性只有在行需要打开时才是可变的。这些行被排序;需要打开的都在不打开的上面。还有一个“Go!”按钮,当前已禁用。我希望在所有需要打开的行都打开时启用它,但我不知道如何向视图层次结构上传递数据。我也不知道合并,所以如果这是答案和例子会很好。谢谢SwiftUI从列表向上传递数据视图层次结构,swift,swiftui,Swift,Swiftui,我有一个SwiftUI应用程序。它有一个行列表,每个行都有一个常量属性表示它是否需要打开,还有一个属性表示它是否打开。第二个属性只有在行需要打开时才是可变的。这些行被排序;需要打开的都在不打开的上面。还有一个“Go!”按钮,当前已禁用。我希望在所有需要打开的行都打开时启用它,但我不知道如何向视图层次结构上传递数据。我也不知道合并,所以如果这是答案和例子会很好。谢谢 导入快捷界面 结构列表视图:视图{ 让模型=[Model.testCase、.testCase2、.testCase3] var b
导入快捷界面
结构列表视图:视图{
让模型=[Model.testCase、.testCase2、.testCase3]
var body:一些观点{
导航视图{
列表(models.sorted{第一,第二
if first.needsToBeOn{return true}
if!second.needsToBeOn{return true}
返回错误
}){model in
导航链接(目标:EmptyView()){
行视图(模型:模型)
}
}
.navigationBarTitle(文本(“模型”))
.navigationBarItems(尾部:按钮(操作:{}){
文本(“开始!”).font(.title)
}.残疾人士(真实))
}
}
}
结构行视图:视图{
让模型:模型
@状态变量=false
var body:一些观点{
HStack{
VStack{
文本(“必须打开:”)
文本(“\(model.needsToBeOn)”)
}
垫片()
VStack{
文本(“拾取”)
切换(isOn:$isOn){
正文(“”)
}.labelsHidden().disabled(!model.needsToBeOn)
}
}.填充(7.5)
}
}
结构模型:可识别{
变量id:UUID
让我们一起来吧,布尔
静态let testCase=Model(id:UUID(),needsToBeOn:true)
静态let testCase2=Model(id:UUID(),needsToBeOn:true)
静态let testCase3=Model(id:UUID(),needsToBeOn:false)
}
我没有机会测试,但请尝试下面的代码
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)
}
}看起来它正在工作
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)
}
行
RowView(model:self.$model)
不起作用,因为model
不是@State
变量,所以我将其更改为self.$models[self.models.firstIndex(of:model)!]
如果有更好的方法,请告诉我