Reputation: 466
I am trying to use forEach in HStack and VStack. I am using Text in them and Text is not appearing while running but onAppear print values. Please have a look on my code. Why Text is not appearing? How can I make this work?
@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()
}
}
}
What I am trying to achieve here?
I am trying to create a HStacks with maximum 3 Texts in it. I am using array here only to rendered Text 7 times.
Expected result with array with 7 elements--->
Want to create a VStack of 3 HStacks, In first 2 HStacks I want to render Text 3 times and in last HStack I want only one Text. (Like I have 7 array elements that's why 3 texts in first two hstacks and one in last hstack). If array has 10 elements, then 3 Hstacks of 3 Texts and last Stack with 1 Text. I am unable to render Text because my array is @state var and it refresh view.body every time I remove firstElement from it.
Is there any way to achieve this behaviour I am trying to achieve by using SwiftUI only. I don't want to use UICollection view.
Upvotes: 0
Views: 642
Reputation: 10355
You generally don't want to change a @State variable as a side-effect of the evaluation of body
; in this case, your self.sd.removeFirst()
is causing the body
to be marked as needing to be re-evaluated, so SwiftUI
just keeps calling it until your sd
array is empty, which is why you don't see anything being rendered.
To get the effect you want, this is one way you can do it:
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. Most attempts to modify state within the body
evaluation seem to result in the runtime warning Modifying state during view update, this will cause undefined behavior.
– it seems that your array mutation somehow side-stepped this check, but hopefully that sort of thing will be called out at runtime in the future.
Upvotes: 0