欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SwiftUI List中的TextField

程序员文章站 2024-03-24 11:58:52
...

开发环境:XCode 12.5.1 、MacOS 11.5.1、IOS 14.0

实际开发过程中,会有用List包裹一些TextFiled的情况,我们可以写如下代码实现:

struct ListAndTextField: View {
    
    @State var players = ["Todi", "Messi", "Nimar"]

    var body: some View {
        VStack {
            List(0..<players.count) { index in
                TextField(players[index], text: $players[index])
            }
        }.padding()
    }
}

运行,看起来没有问题。如果我们想增加一个按钮,每次点击增加一个TextField

struct ListAndTextField: View {
    
    @State var players = ["Todi", "Messi", "Nimar"]

    var body: some View {
        VStack {
            List(0..<players.count) { index in
                TextField(players[index], text: $players[index])
            }
            
            Button(action: {
                self.players.append("new player")
            }, label: {
                Text("Add")
            })
        }.padding()
    }
}

点击“Add”,你会发现不但List没有变化,控制台还会有警告提示:

ForEach<Range<Int>, Int, HStack<TextField<Text>>> count (4) != its initial count (3). `ForEach(_:content:)` should only be used for *constant* data. Instead conform data to `Identifiable` or use `ForEach(_:id:content:)` and provide an explicit `id`!

大意是ForEach使用时需要用遵守Identifiable 协议的数据,或者使用ForEach(_:id:content:) 的形式,因为List本身中也是使用了ForEach,所以会出现这个错误提示。

正确写法应该是:

struct ListAndTextField: View {
    
    @State var players = ["Todi", "Messi", "Nimar"]

    var body: some View {
        VStack {
            List {
                ForEach(players.indices, id: \.self) { index in
                    TextField(players[index], text: $players[index])
                }
            }
            
            Button(action: {
                self.players.append("new player")
            }, label: {
                Text("Add")
            })
        }.padding()
    }
}

目前使用SwiftUI 2.0,个人建议还是使用List + ForEach的方式。在SwiftUI 3.0中可以使用如下的写法:

List($players) { $player in
    TextField("...", text: $player)
}

个人还没有用过SwiftUI 3.0,不过这种写法就很符合SwiftUI的风格了。

相关标签: SwiftUI swiftui