Reputation: 6009
How can the order of a VStack be changed during runtime? For HStack, the layout direction can be changed from .leftToRight and .rightToLeft. With ZStack, a zIndex can be adjusted to change order of the views, front to back. Is there something that can be used to change the order of a VStack? In my project, reversing the order top-to-bottom would work.
This is a greatly simplified example with duplication:
struct ContentView: View {
@State var shouldFlip = false
var body: some View {
if shouldFlip {
VStack {
Color(.red)
Color(.blue)
Color(.yellow)
Color(.green)
}
} else {
VStack {
Color(.green)
Color(.yellow)
Color(.blue)
Color(.red)
}
}
}
}
To avoid duplication is there anything like the following but for a VStack with .topToBottom and .bottomToTop:
struct ContentView: View {
@State var shouldFlip = true
var body: some View {
HStack {
Color(.red)
Color(.blue)
Color(.yellow)
Color(.green)
}.environment(\.layoutDirection, shouldFlip ? .rightToLeft : .leftToRight)
}
}
Upvotes: 3
Views: 1588
Reputation: 13970
I would start from opposite end: have underlying data ordered in proper way, and use ForEach
to show it in the order it is stored. That way view itself doesn't need to know anything about the order:
struct ContentView: View {
@State var shouldFlip = true
var items: [Color] = [.red, .blue, .yellow, .green]
var shownItems: [Color] {
shouldFlip ? items.reversed() : items
}
var body: some View {
VStack {
ForEach(shownItems) { item in
item
}
}
}
}
In this case to make example fully compilable, I also need to make Color
Identifiable
:
extension Color: Identifiable {
public var id: UUID {
return UUID()
}
}
but depending on what you actually want to display, this may not be needed if what you have is already Identifiable.
This way you have the logic (order of items) fully separated and independent from the way you want them displayed: today you want VStack
, tomorrow you support rotation, and maybe want HStack
in landscape view... Both will work the same way with pre-arranged data.
Also I wouldn't recommend using .rightToLeft
- it's not for your use case, it's for right-to-left languages support (Hebrew, Arabic)
Upvotes: 5