mirror of
https://github.com/yattee/yattee.git
synced 2026-04-10 17:46:58 +00:00
Yattee v2 rewrite
This commit is contained in:
77
Yattee/Views/Components/SwipeGesture.swift
Normal file
77
Yattee/Views/Components/SwipeGesture.swift
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// SwipeGesture.swift
|
||||
// Yattee
|
||||
//
|
||||
// Custom pan gesture that filters horizontal swipes to avoid conflicts with ScrollView.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
#if os(iOS)
|
||||
|
||||
/// Value passed to gesture callbacks containing translation and velocity.
|
||||
struct SwipeGestureValue {
|
||||
var translation: CGSize = .zero
|
||||
var velocity: CGSize = .zero
|
||||
}
|
||||
|
||||
/// Custom pan gesture recognizer that only begins when horizontal velocity exceeds vertical.
|
||||
/// This prevents conflicts with ScrollView vertical scrolling.
|
||||
@available(iOS 18, *)
|
||||
struct SwipeGesture: UIGestureRecognizerRepresentable {
|
||||
var onBegan: () -> Void
|
||||
var onChange: (SwipeGestureValue) -> Void
|
||||
var onEnded: (SwipeGestureValue) -> Void
|
||||
|
||||
func makeCoordinator(converter: CoordinateSpaceConverter) -> Coordinator {
|
||||
Coordinator()
|
||||
}
|
||||
|
||||
func makeUIGestureRecognizer(context: Context) -> UIPanGestureRecognizer {
|
||||
let gesture = UIPanGestureRecognizer()
|
||||
gesture.delegate = context.coordinator
|
||||
return gesture
|
||||
}
|
||||
|
||||
func updateUIGestureRecognizer(_ recognizer: UIPanGestureRecognizer, context: Context) {}
|
||||
|
||||
func handleUIGestureRecognizerAction(_ recognizer: UIPanGestureRecognizer, context: Context) {
|
||||
let state = recognizer.state
|
||||
let translation = recognizer.translation(in: recognizer.view).toSize
|
||||
let velocity = recognizer.velocity(in: recognizer.view).toSize
|
||||
|
||||
let gestureValue = SwipeGestureValue(translation: translation, velocity: velocity)
|
||||
|
||||
switch state {
|
||||
case .began:
|
||||
onBegan()
|
||||
case .changed:
|
||||
onChange(gestureValue)
|
||||
case .ended, .cancelled:
|
||||
onEnded(gestureValue)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, UIGestureRecognizerDelegate {
|
||||
/// Only begin the gesture when horizontal velocity exceeds vertical velocity.
|
||||
/// This allows ScrollView to handle vertical scrolling while we handle horizontal swipes.
|
||||
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
guard let panGesture = gestureRecognizer as? UIPanGestureRecognizer else {
|
||||
return false
|
||||
}
|
||||
|
||||
let velocity = panGesture.velocity(in: panGesture.view)
|
||||
return abs(velocity.x) > abs(velocity.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension CGPoint {
|
||||
var toSize: CGSize {
|
||||
CGSize(width: x, height: y)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user