Skip to content

Instantly share code, notes, and snippets.

@SlappyAUS
Last active December 24, 2020 11:06
Show Gist options
  • Save SlappyAUS/0b358df913d1ad6a768f886c6a7d4c01 to your computer and use it in GitHub Desktop.
Save SlappyAUS/0b358df913d1ad6a768f886c6a7d4c01 to your computer and use it in GitHub Desktop.
Swipeable Modifier #swift #swiftui #modifiers
//
// SwipeableModifier.swift
// DrinkSum
//
// Created by Greg Eales on 22/12/20.
//
import SwiftUI
struct Swipeable<V>: ViewModifier where V: View {
@State private var dragAmount = CGFloat.zero
@State private var direction: Bool? = nil
let maxDrag: CGFloat
let underView: (CGFloat, CGFloat) -> V
func body(content: Content) -> some View {
ZStack {
HStack {
Spacer()
underView(self.dragAmount, self.maxDrag)
.padding(.leading, 10)
.frame(width: self.maxDrag)
}
content
.offset(x: self.dragAmount)
.gesture(
DragGesture()
.onChanged {
if self.direction == nil {
if self.dragAmount == -self.maxDrag {
self.direction = true
} else if self.dragAmount == 0 {
self.direction = false
} else {
self.direction = $0.translation.width > 0
}
}
if self.direction! {
self.dragAmount = min(0, max(-maxDrag, -maxDrag + max(0, $0.translation.width)))
} else {
self.dragAmount = min(0, max(-maxDrag, min(0,$0.translation.width)))
}
}
.onEnded({ _ in
withAnimation {
self.direction = nil
if self.dragAmount < (self.maxDrag * -0.5) {
self.dragAmount = -self.maxDrag
} else {
self.dragAmount = 0
}
}
})
)
.onTapGesture {
withAnimation {
self.dragAmount = 0
}
}
}
}
}
extension View {
func swipeable<V>(maxDrag: CGFloat, underView: @escaping (CGFloat, CGFloat) -> V) -> some View where V:View {
return self.modifier(Swipeable(maxDrag: maxDrag, underView: underView))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment