* SwiftUI Beta 7 *如何使ForEach Loop中的项目处于活动状态

时间:2019-09-14 19:42:01

标签: list select foreach swiftui

我有一个类型的数据模型:

struct fruit: Identifiable{
    var id = UUID()
    var a: String
    var b: String
    var isActive: Bool
}

和一个数组:

let fruitData=[
    Model(a:"appleImg", b:"Apple", isActive: true),
    Model(a:"pearImg", b:"Pear", isActive: false),
    Model(a:"bananaImg", b:"Banana", isActive: false),
]

有一个如下的RowView:

struct RowView{
    var a = "appleImg"
    var b = "Apple"
    var isActive = true

    var body: some View{    
      HStack(spacing:8){
         Image(a)
         Text(b)
         Spacer()
      }
   }
}

然后,我创建了一个在其中使用ModelArray的视图,并将其循环到主视图中的ForEach中。像这样:

let fruits = fruitData
ForEach(fruits){fruitPiece in
    RowView(a:fruitPiece.a, b:fruitPiece.b, isActive: 
    fruitPiece.isActive)
}

我想根据用户在所选行上的点击来更改isActive-技巧是它应该是单个选择,因此一次只能有1个活动状态。对于SwiftUI还是一个新手,因此非常感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

下面的代码执行您所要求的。但是首先要对您的代码进行一些注释:

  1. 按照惯例,变量名绝不能以大写字母开头(例如,在let ModelArray中)。它使阅读变得更加困难。如果不是对你,对别人。共享代码时(例如在stackoverflow中),请尝试遵循适当的约定。

  2. 您正在调用ForEach(models),但是您尚未定义模型数组(尽管您确实创建了ModelArray)。

  3. 在ForEach内部,您正在呼叫Model(...)。在ForEach内部,您需要一个视图来显示数据。但是在您的代码中,模型是一种数据类型。没有道理。

这是我认为的代码,可以完成您所要求的。当您点击视图时,其isActive标志将切换。为了显示效果,文本颜色会相应更改。

struct Model: Identifiable {
    var id = UUID()
    var a: String
    var b: String
    var c: String
    var isActive: Bool
}

struct ContentView: View {
    @State private var modelArray = [
        Model(a:"hi", b:"I like", c: "potatoes", isActive: true),
        Model(a:"hi", b:"I like", c: "potatoes", isActive: false),
        Model(a:"hi", b:"I like", c: "potatoes", isActive: false),
    ]

    var body: some View {
        ForEach(modelArray.indices, id: \.self){ idx in

            Text("\(self.modelArray[idx].a) \(self.modelArray[idx].b) \(self.modelArray[idx].c)")
                .foregroundColor(self.modelArray[idx].isActive ? .red : .green)
                .onTapGesture {
                    self.modelArray[idx].isActive = true

                    for i in self.modelArray.indices {
                        if i != idx { self.modelArray[i].isActive = false }
                    }
                }
        }
    }
}