Last active
December 14, 2020 20:53
-
-
Save aheze/3d5820c03616d25e21376ad561798e9e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// iOS 13 version here: https://gist.github.com/aheze/bd4e1990dbeda66e60c00c6341451930 | |
/// Note: iOS 13 version has a "bug" where adding a second finger freezes the touch event | |
/// More details here: https://developer.apple.com/forums/thread/660070 | |
/// Thanks @brentbrinkley for discovering the bug! | |
/// if you're on iPad Swift Playgrounds and you put all of this code in a seperate file, | |
/// you need to make everything public so that the compiler detects it. | |
/// the possible states of the button | |
public enum ButtonState { | |
case pressed | |
case notPressed | |
} | |
/// ViewModifier allows us to get a view, then modify it and return it | |
public struct TouchDownUpEventModifier: ViewModifier { | |
/// Properties marked with `@GestureState` automatically resets when the gesture ends/is cancelled | |
/// for example, once the finger lifts up, this will reset to false | |
/// this functionality is handled inside the `.updating` modifier | |
@GestureState private var isPressed = false | |
/// this is the closure that will get passed around. | |
/// we will update the ButtonState every time your finger touches down or up. | |
let changeState: (ButtonState) -> Void | |
/// a required function for ViewModifier. | |
/// content is the body content of the caller view | |
public func body(content: Content) -> some View { | |
/// declare the drag gesture | |
let drag = DragGesture(minimumDistance: 0) | |
/// this is called whenever the gesture is happening | |
/// because we do this on a `DragGesture`, this is called when the finger is down | |
.updating($isPressed) { (value, gestureState, transaction) in | |
/// setting the gestureState will automatically set `$isPressed` | |
gestureState = true | |
} | |
return content | |
.gesture(drag) /// add the gesture | |
.onChange(of: isPressed, perform: { (pressed) in /// call `changeState` whenever the state changes | |
/// `onChange` is available in iOS 14 and higher. | |
if pressed { | |
self.changeState(.pressed) | |
} else { | |
self.changeState(.notPressed) | |
} | |
}) | |
} | |
/// if you're on iPad Swift Playgrounds and you put all of this code in a seperate file, | |
/// you need to add a public init so that the compiler detects it. | |
public init(changeState: @escaping (ButtonState) -> Void) { | |
self.changeState = changeState | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment