我有以下组件可以呈现半透明字符网格:
var body: some View {
VStack{
Text("\(self.settings.numRows) x \(self.settings.numColumns)")
ForEach(0..<self.settings.numRows){ i in
Spacer()
HStack{
ForEach(0..<self.settings.numColumns){ j in
Spacer()
// why do I get an error when I try to multiply i * j
self.getSymbol(index:j)
Spacer()
}
}
Spacer()
}
}
}
Run Code Online (Sandbox Code Playgroud)
settings 是一个环境对象
每当settings更新时,最外层的文本VStack都会正确更新。但是,视图的其余部分不会更新(网格具有与以前相同的尺寸)。为什么是这样?
第二个问题:为什么不能访问i内部ForEach循环并将其作为参数传递给函数?
我在外ForEach循环出现错误:
无法推断通用参数“数据”
Joh*_* M. 59
您的 ForEach 需要id: \.self在您的范围之后添加。
ForEach 有几个初始化器。您正在使用
init(_ data: Range<Int>, @ViewBuilder content: @escaping (Int) -> Content)
Run Code Online (Sandbox Code Playgroud)
wheredata 必须是一个常数。
如果您的范围可能会发生变化(例如,您正在从数组中添加或删除项目,这将更改上限),那么您需要使用
init(_ data: Data, id: KeyPath<Data.Element, ID>, content: @escaping (Data.Element) -> Content)
Run Code Online (Sandbox Code Playgroud)
您为id参数提供一个键路径,它唯一地标识ForEach循环的每个元素。在 a 的情况下,Range<Int>您循环的元素是一个Int指定数组索引的元素,该索引是唯一的。因此,您可以简单地使用\.self键路径让 ForEach 通过其自己的值标识每个索引元素。
下面是它在实践中的样子:
struct ContentView: View {
@State var array = [1, 2, 3]
var body: some View {
VStack {
Button("Add") {
self.array.append(self.array.last! + 1)
}
// this is the key part v--------v
ForEach(0..<array.count, id: \.self) { index in
Text("\(index): \(self.array[index])")
//Note: If you want more than one views here, you need a VStack or some container, or will throw errors
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你运行它,你会看到当你按下按钮将项目添加到数组时,它们将VStack自动出现在。如果删除“ id: \.self”,您将看到原始错误:
`ForEach(_:content:)` should only be used for *constant* data.
Instead conform data to `Identifiable` or use `ForEach(_:id:content:)`
and provide an explicit `id`!"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7033 次 |
| 最近记录: |