[FEAT] Add trackpad scroll support
Is your feature request related to a problem? Please describe. When using Trackpad, it requires drag and drop operation to change page.
Describe the solution you'd like For Desktop or iPad with Trackpad use-case, two finger scroll is more easier way than drag and drop page. Please consider to support to scroll pages.
Describe alternatives you've considered N/A
Hi @almagest21 , thanks for your feedback. I believe it's not possible to do this natively in SwiftUI? I can't find any documentation on it, the only accepted answer is "wrapping an NSView into SwiftUI and use scrollWheel". However this defeats the purpose of the library 😕
I have been able to find a workaround for this (sort off)
I made changes to PagerContent. I have a variable @State private var mouseIsOnCards = false
on stack I have
let stack = HStack(spacing: interactiveItemSpacing) {
ForEach(dataDisplayed, id: id) { item in
Group {
if self.isInifinitePager && self.isEdgePage(item) {
EmptyView()
} else {
self.content(item.element)
.frame(size: self.pageSize)
.scaleEffect(self.scale(for: item))
.rotation3DEffect((self.isHorizontal ? .zero : Angle(degrees: -90)) - self.scrollDirectionAngle,
axis: (0, 0, 1))
.rotation3DEffect(self.angle(for: item),
axis: self.axis)
.opacity(opacity(for: item))
}
}
}
.offset(x: self.xOffset, y : self.yOffset)
}
.frame(size: size)
.onAppear(perform: monitorScrollWheelEvents)
.onHover { bool in
withAnimation(.spring()) {
mouseIsOnCards = bool
}
}
and finally
private func monitorScrollWheelEvents() {
#if os(macOS)
NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel]) { event in
if mouseIsOnCards {
if event.phase == .changed {
let animation = draggingAnimation.animation
withAnimation(animation) {
let x = (event.scrollingDeltaY)
self.pagerModel.draggingOffset = self.draggingOffset + x
self.onDraggingChanged?(Double(-self.draggingOffset / self.pageDistance))
self.pagerModel.objectWillChange.send()
}
}
if event.phase == .ended {
onDragGestureEnded()
}
}
return event
}
#endif
}
This is preliminary and I have not extensively tested it. That's why I can't PR. You will notice that many precautions implemented in func onDragChanged(with value: DragGesture.Value) are not present.
This works for vertical Pager. If you want for horizontal you can use let x = (event.scrollingDeltaX)
This is the only feature holding me back from using this awesome library. It would be really nice if you somehow managed to add this.