I want to place an image either on top of, or between lines, depending on the position
variable:
struct ContentView: View {
@State var position = 5
var body: some View {
VStack(spacing: 20){
ForEach(1...15, id: \.self){i in
ZStack{
if i%2 != 0{
Rectangle()
.frame(height: 4)
.foregroundColor(.white)
}
if i == position{
Circle()
.frame(height: 30)
.foregroundColor(.white)
}
}
}
}
}
}
This is the result:
If i
is odd the line (Rectangle
) is drawn.
If i == position
, the Circle
is drawn: it is on top of the line, or if no line was drawn, it is between the other lines.
My problem is that the lines don’t remain fixed when I change the value of position
because the Circle
takes up space and pushes the lines away from it.
The lines above and below the circle get pushed away when the Circle
is between two lines which causes the lines to move back and forth as the Circle
is either between or on top of lines.
How would I go about fixing this?
There is two issues here: non-constant height of row (because row with circle and w/o circle have different heights) and conditional layout (absent rectangles gives different layout).
Here is a possible solution. Tested with Xcode 13.4 / iOS 15.5
struct ContentView: View {
@State var position = 4
var body: some View {
VStack(spacing: 20){
ForEach(1...15, id: \.self){i in
ZStack {
Rectangle()
.frame(height: 4)
.foregroundColor(i%2 == 0 ? .clear : .white) // << here !!
if i == position{
Circle()
.foregroundColor(.white)
.frame(height: 30)
}
}.frame(height: 4) // << here !!
}
}
}
}