我正在尝试在HStack和VStack中使用forEach。我在其中使用了Text,并且在运行时不会显示Text,而是显示onAppear打印值。请看一下我的代码。为什么文本没有出现?我该如何工作?
@State var sd = ["1","2","3","4","5","6","7"]
VStack {
ForEach(0...sd.count/3) { _ in
HStack {
ForEach(0...2) { _ in
if(self.sd.isEmpty) {
} else {
Text("Test")
.onAppear() {
if(!self.sd.isEmpty) {
print("i appeared")
self.sd.removeFirst()
}
}
}
}
Spacer()
}
}
}
我想在这里实现什么?
我正在尝试创建一个最多包含3个文本的HStack。我在这里使用数组仅渲染文本7次。
具有7个元素的数组的预期结果--->
要创建一个由3个HStack组成的VStack,在前2个HStack中,我想渲染3次Text,在最后一个HStack中,我只想要一个Text。 (就像我有7个数组元素一样,这就是为什么前两个hstack中有3个文本,最后一个hstack中有3个文本的原因)。如果数组有10个元素,则3个3个文本的堆栈,最后一个1个文本的堆栈。我无法呈现Text,因为我的数组是@state var,每次我从中删除firstElement时都会刷新view.body。
有什么办法可以实现这种行为,我只想通过SwiftUI来实现。我不想使用UICollection视图。
答案 0 :(得分:0)
您通常不希望更改@State变量作为对body
求值的副作用;在这种情况下,您的self.sd.removeFirst()
导致body
被标记为需要重新评估,因此SwiftUI
一直调用它,直到您的sd
数组为空,这就是为什么您看不到任何渲染的原因。
要获得想要的效果,这是一种实现方法:
import SwiftUI
struct ContentView : View {
@State private var sd = ["1","2","3","4","5","6","7"]
private let columns = 3
var body: some View {
VStack {
ForEach(Array(stride(from: 0, to: sd.count, by: columns))) { row in
HStack {
ForEach(0..<self.columns) { col in
if row + col < self.sd.count {
Text("\(self.sd[row + col])")
}
}
}
}
}
}
}
P.S。在body
评估中修改状态的大多数尝试似乎都会导致运行时警告Modifying state during view update, this will cause undefined behavior.
–似乎您的数组突变以某种方式绕开了该检查,但希望这种情况可以在将来运行。