Trying to layout a stack of "chips" in two side-by-side panels in a mirrored way, fanned out from the middle:
The right panel looks correct, the left is messed up. What am I doing wrong?
Here is the code:
import SwiftUI
let w = UIScreen.main.bounds.width
struct ContentView: View {
var body: some View {
HStack(spacing:0) {
VStack(alignment: .trailing) {
ForEach(1 ..< 5, id: \.self) { row in
HStack(spacing: -80) {
ForEach(1 ... row, id: \.self) { _ in
Circle().fill(.white).stroke(.black, lineWidth: 1).frame(width: 50, height: 50)
}
}.background(.red)
}
}.frame(maxWidth: .infinity, alignment: .trailing)
.frame(width: w / 2)
.background(Color.gray)
VStack(alignment: .leading) {
ForEach(1 ..< 5, id: \.self) { row in
HStack(spacing: -20) {
ForEach(1 ... row, id: \.self) { _ in
Circle().fill(.white).stroke(.black, lineWidth: 1).frame(width: 50, height: 50)
}
}
}
}.frame(maxWidth: .infinity, alignment: .leading)
.frame(width: w / 2)
.background(Color.black)
}
}
}
#Preview {
ContentView()
}
In the first VStack
, you could try setting a zIndex
on the circles, so that the circles that come first in the row (from left to right) are shown "higher". The spacing should also be -20, like in the second VStack
:
VStack(alignment: .trailing) {
ForEach(1 ..< 5, id: \.self) { row in
HStack(spacing: -20) { // 👈 changed
ForEach(1 ... row, id: \.self) { i in // 👈 changed
Circle()
.fill(.white)
.stroke(.black, lineWidth: 1)
.frame(width: 50, height: 50)
.zIndex(Double(-i)) // 👈 added
}
}
.background(.red)
}
}
.frame(maxWidth: .infinity, alignment: .trailing)
.frame(width: w / 2)
.background(Color.gray)
Btw, UIScreen.main
is deprecated and doesn't work with iPad split screen. You might want to consider using a GeometryReader
to measure the screen width instead:
GeometryReader { geo in
let w = geo.size.width
HStack(spacing:0) {
// content as before
}
.frame(maxHeight: .infinity)
}