'How to reverse SwiftUI ZStack order?
trying to recreate a next/previous item on a stack of cards. I have my cards in a ZStack. The problem I’m having is that by default ZStack are in reverse order (first item in array is at the bottom of the stack).
Here’s what the code looks like at the moment:
The Data
var userData: [User] = [
User(id: 0, firstName: "Cindy", lastName: "Jones", age: 23, mutualFriends: 4, imageName: "image1", occupation: "Coach"),
User(id: 1, firstName: "Mark", lastName: "Bennett", age: 27, mutualFriends: 0, imageName: "image2", occupation: "Insurance Agent"),
User(id: 2, firstName: "Clayton", lastName: "Delaney", age: 20, mutualFriends: 1, imageName: "image23, occupation: "Food Scientist"),
]
Content View (where the data gets passed in)
CardsView(users: userData).tab(title: "Tinder Cards", image: "music.note")
The Card Stack
struct CardStack: View {
@State var users: [User]
var body: some View {
ZStack {
ForEach(self.users, id: \.self) { user in
if user.id > self.maxID - 4 { //only show 4 at a time
CardView(user: user)
}
}
}
}
}
At the moment, I can think of 2 ways to solve this:
- Reverse the order of the array.
- Change the zIndex on individual cards.
Because the array is already in the correct order for all other screens, the first option seems like a bad idea (and maybe slow if there are a lot of cards). That said I’ve tried passing the data into the view with CardsView(users: userData.reversed())
and it seems to have no effect.
The second option is to change the zIndex on individual cards. In this example, every User has an Int as an ID, so I thought I could just negate it like this, but it doesn’t have any effect:
ZStack {
ForEach(self.users, id: \.self) { user in
if user.id > self.maxID - 4 {
CardView(user: user)
.zIndex(Double(user.id) * -1)
}
}
}
And, curiously, if I change the id’s to be negative when they array is created like User(id: -1,
they’re not visible at all. Does anyone have any ideas or know what I’m getting/doing wrong here?
Thanks :3
Solution 1:[1]
import SwiftUI
struct ReverseZView: View {
let values: [Int] = [0,1,2,3,4,5,6,7,8,9]
let colors: [Color] = [.red,.yellow,.orange,.green,.blue,.gray,.black]
var body: some View {
VStack{
ZStack{
ForEach(Array(values.enumerated()), id:\.offset, content: { (index, value) in
Circle()
.overlay(Text(value.description).foregroundColor(.white))
.frame(width: 40)
.foregroundColor(colors.randomElement()!)
//use the index to find the opposite value
.zIndex(Double(values.count - index))
})
}
ZStack{
ForEach(Array(values.enumerated()), id:\.offset, content: { (index, value) in
Circle()
.overlay(Text(value.description).foregroundColor(.white))
.frame(width: 40)
.foregroundColor(colors.randomElement()!)
//Just making the index negative should also reverse
.zIndex(-Double(index))
})
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |