Skip to content

Instantly share code, notes, and snippets.

@sulaimansust
Created April 18, 2024 11:42
Show Gist options
  • Save sulaimansust/2d674951035a28df861bc0ed0c9aa77a to your computer and use it in GitHub Desktop.
Save sulaimansust/2d674951035a28df861bc0ed0c9aa77a to your computer and use it in GitHub Desktop.
SwipeGesture SwiftUI
//
// Copyright © 2024 Liebherr-Hausgeräte GmbH. All rights reserved.
//
import SwiftUI
/// A swiping motions that invokes an swipe event telling the direction of the swipe.
/// Example:
/// Add a swipe gesture to a ``Circle`` and change its color while the user
/// performs the swipe gesture:
///
/// struct SwipeGestureView: View {
/// var body: some View {
/// Circle()
/// .fill(self.isDragging ? Color.red : Color.blue)
/// .frame(width: 500, height: 500, alignment: .center)
/// .onSwipe { direction in
/// self.direction = direction.rawValue
/// }
/// }
/// }
public struct SwipeGesture: Gesture {
/// Represent swipe direction on the screen
public enum Direction {
// swiftlint:disable identifier_name
case left, right, up, down
}
/// Value that hold the direction of the SwipeGesture
public typealias Value = Direction
/// Minimum distance to invoke Swipe event
private let minimumDistance: CGFloat
private let coordinateSpace: CoordinateSpace
// swiftlint:disable magic_numbers
public init(minimumDistance: CGFloat = 20, coordinateSpace: CoordinateSpace = .local) {
self.minimumDistance = minimumDistance
self.coordinateSpace = coordinateSpace
}
public var body: AnyGesture<Value> {
AnyGesture(
DragGesture(minimumDistance: minimumDistance, coordinateSpace: coordinateSpace)
.map { value in
let horizontalAmount = value.translation.width
let verticalAmount = value.translation.height
if abs(horizontalAmount) > abs(verticalAmount) {
return horizontalAmount < 0 ? .left : .right
} else {
return verticalAmount < 0 ? .up : .down
}
}
)
}
}
extension View {
/// Provide swipe gesture to any view.
///
public func onSwipe(minimumDistance: CGFloat = 20,
coordinateSpace: CoordinateSpace = .local,
perform: @escaping (SwipeGesture.Direction) -> Void) -> some View {
gesture(
SwipeGesture(minimumDistance: minimumDistance, coordinateSpace: coordinateSpace)
.onEnded(perform)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment