I am trying to reproduce the macos apple calendar but I'm having issues making the horizontal infinite scroll. The calendar needs to display 7 days at all times meaning that the user can't scroll at any position
This is my current code where I put a rectangle at the beginning of every day cell like this:
I already have a ScrollViewReader with the ids of every day cell but I can't get it to stop on the beginning of each day cell.
@State private var loadedDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun","Mon1", "Tue1", "Wed1", "Thu1", "Fri1", "Sat1", "Sun1"]
@State private var scrollPos: String?
var body: some View {
GeometryReader { geomtry in
Text("\(scrollPos ?? "nil")")
ScrollViewReader { proxy in
ScrollView (.horizontal) {
LazyHStack(spacing: 10) {
ForEach($loadedDays, id: \.self) { day in
HStack {
Rectangle()
.frame(width: 5, height: 5, alignment: .leading)
.id("r" + day.wrappedValue)
VStack {
Text(day.wrappedValue)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.id(day.wrappedValue)
Rectangle()
.frame(width: 5, height: 5, alignment: .trailing)
.id("l" + day.wrappedValue)
}.border().frame(width: geomtry.size.width/7)
}
}
.padding()
.scrollTargetLayout()
}
.defaultScrollAnchor(.center)
.onChange(of: scrollPos) { old, new in
if(new != nil && !new!.starts(with: "r")) {
withAnimation {
proxy.scrollTo("r" + new!, anchor: .leading)
}
}
}
}
.scrollPosition(id: $scrollPos)
}
}
With this code sometimes it works but with no animation but most of the time it lets me scroll anywhere.
From the comment of Sweeper. I used the scrollTargetBehavior(.viewAligned) to solve the problem
GeometryReader { geometry in
ScrollViewReader { proxy in
ScrollView (.horizontal) {
LazyHStack(spacing: 0) {
ForEach($loadedDays, id: \.self) { day in
HStack {
Rectangle()
.frame(width: 5, height: 5, alignment: .leading)
VStack {
Text(day.wrappedValue)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
Rectangle()
.frame(width: 5, height: 5, alignment: .trailing)
}
.border()
.frame(width: geometry.size.width/7)
}
}
.scrollTargetLayout()
}
//.defaultScrollAnchor(.center)
.scrollTargetBehavior(.viewAligned)
.defaultScrollAnchor(.leading)
}