在绑定调用中使用 SwiftUI ForEach 的迭代器变量

Posted

技术标签:

【中文标题】在绑定调用中使用 SwiftUI ForEach 的迭代器变量【英文标题】:Using SwiftUI ForEach's iterator variable in a binding call 【发布时间】:2020-02-13 14:47:45 【问题描述】:

我正在尝试在需要绑定的视图中使用 ForEach 的迭代器变量。

import SwiftUI

struct MyStruct: Identifiable 
    public var id = UUID()
    var name: String
    var repetitions: Int



struct ContentView: View 
    @State private var mystructs :[MyStruct] = [
        MyStruct(name: "John", repetitions: 3),
        MyStruct(name: "Mark", repetitions: 9)
    ]

    var body: some View 

        List 
            ForEach (mystructs)  st in
                VStack 
                    Text("\(st.name)")
                    TextField("Name", text: self.$mystructs[0].name)
                    TextField("Name", text: $st.name) // <- Got "Ambiguous reference..." error
                
            
        
    

ForEach 迭代器有效,正如 Text 视图对 st.name 的使用所证明的那样。第一个 TextField 演示了绑定到 mystructs 元素的工作。但是,对于第二个 TextField 这是我的真实用例,会导致以下编译器错误:

- Use of unresolved identifier $st
- Ambiguous reference to member of 'subscript'

有什么想法吗?

【问题讨论】:

你想做什么? 尝试使列表动态化,我可以在其中添加/删除数组元素并同时修改元素。这是一个简化的代码sn-p;在我的代码中,我有一个自定义 View 而不是 TextField 并且需要绑定。 【参考方案1】:

$st 未解决,因为 'st' 不是状态变量,不能用于绑定目的。 $mystructs 也可以工作,因为它被声明为 State 变量并且可以用于绑定。

希望这对你有用!谢谢!

【讨论】:

【参考方案2】:

在所描述的场景中,可以完成以下操作

ForEach (mystructs.indices)  i in
    VStack 
        Text("\(self.mystructs[i].name)")
        TextField("Name", text: self.$mystructs[i].name)
    

更新: 更通用用例的变体

ForEach (Array(mystructs.enumerated()), id: \.element.id)  (i, item) in
    VStack 
        Text("\(item.name)")
        TextField("Name", text: self.$mystructs[i].name)
    

【讨论】:

谢谢,但不幸的是,在我的实际用例中,数组中的元素数量也会发生变化。例如。如果视图中某处的按钮将另一个元素附加到数组中,则视图不会显示新元素,因为计数将保持不变,尽管没有编译器错误。 @Hampden123,通用案例也有变体,请参阅更新。【参考方案3】:

基于@Asperi 的回答,这也有效:

var body: some View 
    List 
        Button("Add") 
            self.mystructs.append(MyStruct(name: "Pepe", repetitions: 42))
        
        ForEach(mystructs.indices, id: \.self)  index in
            VStack 
                Text(self.mystructs[index].name)
                TextField("Name", text: self.$mystructs[index].name)
            
        
    

【讨论】:

以上是关于在绑定调用中使用 SwiftUI ForEach 的迭代器变量的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 是不是可以在 ForEach 中传递绑定范围?

在 ForEach 循环中绑定时,如何阻止 SwiftUI TextField 失去焦点?

SwiftUI - 将 ForEach 与不符合可识别/可散列的绑定数组一起使用

从 SwiftUI 中的列表中删除绑定

SwiftUI 自定义 List 不能在 ForEach 中使用 Binding

如何将 SwiftUI 视图绑定到数组中元素的属性