mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Swift
		
	
| //
 | |
| //  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
 | |
| //
 | |
| 
 | |
| import UIKit.UIGestureRecognizerSubclass
 | |
| 
 | |
| public struct PanDirection: OptionSet {
 | |
|     public let rawValue: Int
 | |
|     public init(rawValue: Int) {
 | |
|         self.rawValue = rawValue
 | |
|     }
 | |
| 
 | |
|     public static let left  = PanDirection(rawValue: 1 << 0)
 | |
|     public static let right = PanDirection(rawValue: 1 << 1)
 | |
|     public static let up    = PanDirection(rawValue: 1 << 2)
 | |
|     public static let down  = PanDirection(rawValue: 1 << 3)
 | |
| 
 | |
|     public static let horizontal: PanDirection = [.left, .right]
 | |
|     public static let vertical: PanDirection = [.up, .down]
 | |
|     public static let any: PanDirection = [.left, .right, .up, .down]
 | |
| }
 | |
| 
 | |
| public class DirectionalPanGestureRecognizer: UIPanGestureRecognizer {
 | |
| 
 | |
|     let direction: PanDirection
 | |
| 
 | |
|     public init(direction: PanDirection, target: AnyObject, action: Selector) {
 | |
|         self.direction = direction
 | |
| 
 | |
|         super.init(target: target, action: action)
 | |
|     }
 | |
| 
 | |
|     override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
 | |
|         // Only start gesture if it's initially in the specified direction.
 | |
|         if state == .possible {
 | |
|             guard let touch = touches.first else {
 | |
|                 return
 | |
|             }
 | |
| 
 | |
|             let previousLocation = touch.previousLocation(in: view)
 | |
|             let location = touch.location(in: view)
 | |
|             let deltaY = previousLocation.y - location.y
 | |
|             let deltaX = previousLocation.x - location.x
 | |
| 
 | |
|             let isSatisified: Bool = {
 | |
|                 if abs(deltaY) > abs(deltaX) {
 | |
|                     if direction.contains(.up) && deltaY < 0 {
 | |
|                         return true
 | |
|                     }
 | |
| 
 | |
|                     if direction.contains(.down) && deltaY > 0 {
 | |
|                         return true
 | |
|                     }
 | |
|                 } else {
 | |
|                     if direction.contains(.left) && deltaX < 0 {
 | |
|                         return true
 | |
|                     }
 | |
| 
 | |
|                     if direction.contains(.right) && deltaX > 0 {
 | |
|                         return true
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 return false
 | |
|             }()
 | |
| 
 | |
|             guard isSatisified else {
 | |
|                 return
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Gesture was already started, or in the correct direction.
 | |
|         super.touchesMoved(touches, with: event)
 | |
| 
 | |
|         if state == .began {
 | |
|             let vel = velocity(in: view)
 | |
|             switch direction {
 | |
|             case .left, .right:
 | |
|                 if fabs(vel.y) > fabs(vel.x) {
 | |
|                     state = .cancelled
 | |
|                 }
 | |
|             case .up, .down:
 | |
|                 if fabs(vel.x) > fabs(vel.y) {
 | |
|                     state = .cancelled
 | |
|                 }
 | |
|             default:
 | |
|                 break
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |