From 0291829c9aa60b2794d27dd136f504493639e39a Mon Sep 17 00:00:00 2001 From: Gustav Sundin Date: Fri, 20 Oct 2017 17:06:51 +0200 Subject: [PATCH] Readded code to handle rapid swicks At the moment we only support this when horizontal swipes is the only swipe direction allowed. --- KSSwipeStack/Classes/SwipeHelper.swift | 24 ++++++++++++++++++++++++ KSSwipeStack/Classes/SwipeView.swift | 17 ++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/KSSwipeStack/Classes/SwipeHelper.swift b/KSSwipeStack/Classes/SwipeHelper.swift index 56fe91f..ada7ced 100644 --- a/KSSwipeStack/Classes/SwipeHelper.swift +++ b/KSSwipeStack/Classes/SwipeHelper.swift @@ -159,6 +159,30 @@ class SwipeHelper { return Double(abs(cardCenter.y - self.screenSize.height / 2)) } + /// Calculate a proper destination for a dismissal of a view based on its position + /// Places the view far to the left if the view is to the left the the center of the screen and vice versa. + /// - Parameter card: View which endpoint to calculate + /// - Returns: Proper destination for the view + func calculateEndpoint(_ card: UIView) -> CGPoint { + let deltaX = card.center.x - screenSize.width / 2 + let deltaY = card.center.y - screenSize.height / 2 + + let k = deltaY / deltaX + let toX = deltaX < 0 ? -screenSize.height / 2 : screenSize.width + screenSize.height / 2 + return CGPoint(x: toX, y: toX * k) + } + + /// Calculate a proper destination for a dismissal of a view based on current velocity + /// Places the view far to the left if the view is currently moving to the left and vice versa. + /// The angle from the center to the proposed destination of the view is based on the angle of the velocity vector + /// - Parameter card: View which endpoint to calculate + /// - Returns: Proper destination for the view + func calculateEndpoint(_ card: UIView, basedOn velocity: CGPoint) -> CGPoint { + let k = velocity.y / velocity.x + let toX = velocity.x < 0 ? -screenSize.height / 2 : screenSize.width + screenSize.height / 2 + return CGPoint(x: toX, y: toX * k) + } + /// Converts a position with coordinates with the origin of the screen as origo to one using the center of the screen as origo. /// Can be used to convert a origin value to a center value refering to the same positioning of a full screen view. /// - Parameter center: Position using origin as origo diff --git a/KSSwipeStack/Classes/SwipeView.swift b/KSSwipeStack/Classes/SwipeView.swift index 13de824..c0a5e7b 100644 --- a/KSSwipeStack/Classes/SwipeView.swift +++ b/KSSwipeStack/Classes/SwipeView.swift @@ -318,7 +318,22 @@ public class SwipeView: UIView { isUserInteractionEnabled = !options.freezeWhenDismissing - let toPoint = swipeHelper.convertToCenter(origin: direction.getSwipeEndpoint()) + var toPoint = swipeHelper.convertToCenter(origin: direction.getSwipeEndpoint()) + + if options.allowHorizontalSwipes && !options.allowVerticalSwipes { + // Special case to better handle rapid flicks + if !(card.frame.origin.x == 0 && card.frame.origin.y == 0) { + if card.center.x > options.screenSize.width / 2 { + toPoint = swipeHelper.calculateEndpoint(card) + } else if let gesture = gesture as? UIPanGestureRecognizer{ + let velocity = gesture.velocity(in: self) + if !(velocity.x == 0 && velocity.y == 0) { + toPoint = swipeHelper.calculateEndpoint(card, basedOn: velocity) + } + } + } + } + swipeHelper.moveFastAndTransform(card, toPoint: toPoint, completion: { completion() self.showNextCard()