Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class GTForceTouchGestureRecognizer: UIGestureRecognizer {
- internal var deepPressedAt: TimeInterval = 0
- internal var gestureParameters: (target: AnyObject?, action: Selector)
- internal var hardTriggerMinTime: TimeInterval
- internal let feedbackGenerator = UIImpactFeedbackGenerator.init(style: .medium)
- internal let threshold: CGFloat
- internal var deepPressed: Bool = false {
- didSet {
- guard deepPressed, !oldValue else {
- return
- }
- deepPressedAt = NSDate.timeIntervalSinceReferenceDate
- }
- }
- public override var state: UIGestureRecognizer.State {
- didSet {
- guard oldValue != state else {
- return
- }
- switch state {
- case .began:
- feedbackGenerator.prepare()
- case .ended:
- feedbackGenerator.impactOccurred()
- _ = gestureParameters.target?.perform(gestureParameters.action, with: self)
- default:
- return
- }
- }
- }
- required public init(target: AnyObject?, action: Selector, threshold: CGFloat = 0.75, hardTriggerMinTime: TimeInterval = 0.5) {
- self.gestureParameters = (target, action)
- self.threshold = threshold
- self.hardTriggerMinTime = hardTriggerMinTime
- super.init(target: nil, action: nil)
- }
- override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
- handleTouch(touches.first)
- }
- override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
- handleTouch(touches.first)
- }
- override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
- state = deepPressed ? UIGestureRecognizer.State.ended : UIGestureRecognizer.State.failed
- deepPressed = false
- super.touchesEnded(touches, with: event)
- }
- internal func handleTouch(_ touch: UITouch?) {
- guard view != nil, let touch = touch, touch.force != 0 && touch.maximumPossibleForce != 0 else {
- return
- }
- let forcePercentage = touch.force / touch.maximumPossibleForce
- if deepPressed && forcePercentage <= 0 {
- state = UIGestureRecognizer.State.ended
- return
- }
- handleForceTouch(with: forcePercentage)
- }
- private func handleForceTouch(with forcePercentage: CGFloat) {
- let currentTime = NSDate.timeIntervalSinceReferenceDate
- if !deepPressed && forcePercentage >= threshold {
- deepPressed = true
- state = UIGestureRecognizer.State.began
- return
- }
- if deepPressed && currentTime - deepPressedAt > hardTriggerMinTime && forcePercentage == 1.0 {
- state = UIGestureRecognizer.State.ended
- }
- }
- }
Add Comment
Please, Sign In to add comment