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

Posted

技术标签:

【中文标题】*SwiftUI Beta 7* 如何使 ForEach 循环中的项目处于活动状态【英文标题】:*SwiftUI Beta 7* How to give item in ForEach Loop an active state 【发布时间】:2019-09-14 19:42:01 【问题描述】:

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

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 - 诀窍是它应该是一个选择,因此一次只有一个活动状态。对 SwiftUI 来说还是新手,因此非常感谢您的帮助:)

【问题讨论】:

有什么问题?您找不到index 吗?你不能改变数组的元素?属性是恒定的?运行时错误或构建时间?要不然是啥?这里出现了很多问题。 老实说,您的问题含糊不清——至少就实际问题而言。那么我们把SwiftUI 去掉怎么样。您的模型有一个良好的开端。还有一个(非常)好的例子,其中......我们称它为第一个元素是唯一一个活跃的元素。 (我建议更改您的示例,使每个元素在UUID 之外都是唯一的。请记住,这只是一个示例。)现在假设您希望数组中的第三个元素为isActive = true。你会怎么做? (提示,这是基本的编码,不管是什么语言。)问题是,你没有表现出来。 (续...) 如果您可以在您的代码中向我们展示这一点,那么我们可以缩小范围。现在您有... List (请注意,我们中的一些人仍然在 SwiftUI 中使用 UITableViews )并希望用户点击第三个元素并...在您的模型中使用您的函数,这可能是 @987654334 @? (提示,现在使用的是 Swift、SwiftUI 和 Combine。)您在查找正在点击的单元格/行时遇到问题吗?或者转换该行以找到UUID,这可能不是可见视图的一部分。长 cmets 短 - 这一切中哪一个是你的问题? 【参考方案1】:

下面的代码可以满足您的要求。但是首先对您的代码进行一些 cmets:

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

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

    在您的 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 
                    
                
        
    

【讨论】:

嘿,感谢您的一般提示,其中一些我已经在实际代码中完成了,但遗憾的是无法分享实际代码,所以做了一个快速示例来说明我正在尝试的内容去做!我设法做到了你在这里所做的事情,但我一直在努力只将其中一个文本行设为红色。感谢您迄今为止的帮助! 哦,我没有理解最后一个要求。我修改了代码以使选择独占。基本上,当您点击任何一行时,您会清除其余的行。或者,您可以使用单个 Int 值来指示您的哪一行是活动的,而不是为每个项目设置一个 isActive 标志。这取决于您的需求。

以上是关于*SwiftUI Beta 7* 如何使 ForEach 循环中的项目处于活动状态的主要内容,如果未能解决你的问题,请参考以下文章

带有 Xcode 11 beta 7 的 SwiftUI 未更新 List / ForEach 的内容

MR_importFromObject 方法在 XCode 7.1 beta (Swiftui 2.0) 中不起作用

如何使 CocoaPods 项目在 OS X El Capitan 和 Xcode 7 Beta 上运行?

如何在数组大小更改后刷新 ForEach 显示元素的数量(SwiftUI,Xcode 11 Beta 5)

如何在 SwiftUI 中使视图的高度从 0 动画到高度?

swiftui 请求 渲染数据