I am iterating an array of simple structs, containing a name and a color. For each element I am displaying a rectangle with the specified color and a machting text element.
All of this is inside a ZStack
, so be able to se all the elements, I am offsetting the rectangles, depending on their index in the array.
The problem is, I am trying to create a vertical scrollView, but it wont scroll. I keeps snapping back to the top.
This is my code:
ScrollView{
ZStack {
ForEach(Array(bookTags.enumerated()), id: \.element.id) { index, tag in
Rectangle()
.frame(height: 300)
.edgesIgnoringSafeArea(.bottom)
.foregroundColor(Color(hex: tag.color))
.overlay {
VStack {
HStack {
Text(tag.name)
.font(.system(size: 30, weight: .bold, design: .rounded))
.foregroundColor(.white)
Spacer()
}
.padding(.horizontal, 30)
Spacer()
}
.padding(.top, 30)
}
.offset(y: index != 0 ? CGFloat(index) * 75: 0)
} // foreach
} // zstack
} // scroll
UPDATE
Since .offset does not
change the height of the container, I tried using .padding(.top, index != 0 ? CGFloat(index) * 75 : 0)
This seems to fix the scroll issue. But for some reason the last element becomes all weird and funny looking. Like this:
UPDATE 2
When I add this line:
.padding(.top, index != 0 ? CGFloat(index) * 75 : 0)
and remove:
.offset(y: index != 0 ? CGFloat(index) * 75: 0)
I also have to remove the framing of the rectangle, if I dont I get this weird behaviour:
When you use offset to change the position of a view, it has no impact on the size of the view, so it has no impact on the size of its container either. This means, your ZStack
will only have a height of 300.
Instead of using .offset
, you could add top padding to the rectangles instead:
//.offset(y: index != 0 ? CGFloat(index) * 75: 0)
.padding(.top, index != 0 ? CGFloat(index) * 75: 0)
UPDATE
Following your updates and answers, two more suggested changes:
.edgesIgnoringSafeArea(.bottom)
from the rectanglesScrollView
and ZStack
: ScrollView {
ZStack(alignment: .top) { // alignment added
// content as before
}
}
.edgesIgnoringSafeArea(.bottom)