I added .scrollTargetLayout(), and .scrollPosition(id: $scrollID) to my ScrollView, and then used ForEach in ScrollView to generate 12 rectangles, and the isTaped variable will be converted when those rectangles are clicked. There is a Spacer() below that will appear when isTaped is true. But when I click on those rectangles, they change strangely(the id on rectangle isn't the correct), and the scroll id at the top can also be seen. The scroll id is not really changed. I want to ask why this is?
here is preview: The id change weird on Xcode preview, and it also
This is the preview on Simulator
here is my code below:
struct WeirdScrollView: View {
@State private var isTaped: Bool = false
@State private var scrollID: Int? = 0
var body: some View {
VStack {
VStack {
Text("scroll id: \(scrollID ?? 0)")
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(alignment: .top) {
ForEach(0..<12, id: \.self) { i in
RoundedRectangle(cornerRadius: 25)
.overlay {
Text("id: \(i)")
.foregroundStyle(Color.white)
}
.containerRelativeFrame(.horizontal, count: 3, spacing: 10.0)
.id(i)
.onTapGesture {
withAnimation {
isTaped.toggle()
}
}
}
}
.scrollTargetLayout()
}
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: $scrollID)
if isTaped {
Spacer(minLength: 300)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
I was originally going to make a custom Date Picker(there is only one Date Picker on screen, and user can scroll it horizontal), but when I did the above things(change isTaped), something weird happened to it.
My project need scroll id to binding what rectangle is appear on screen, but when I remove the .scrollPosition(id: $scrollID), and it run very well but not fit what I need
I've made some changes to your code, referring to rob mayoff's answer here. As he says I use
HStackas opposed toLazyHStack. As the picture below indicates, the scroll id text does change. And the ID numbers over the rectangles remain the same. One major changes is such that I haveZStackto encapsulateRoundedRectangleand the IDTextseparately.