Swiftgram/submodules/Display/Display/WindowPanRecognizer.swift
Peter 8f5a4f7dc1 Add 'submodules/Display/' from commit '7bd11013ea936e3d49d937550d599f5816d32560'
git-subtree-dir: submodules/Display
git-subtree-mainline: 9bc996374ffdad37aef175427db72731c9551dcf
git-subtree-split: 7bd11013ea936e3d49d937550d599f5816d32560
2019-06-11 18:44:37 +01:00

82 lines
2.6 KiB
Swift

import Foundation
import UIKit
public final class WindowPanRecognizer: UIGestureRecognizer {
public var began: ((CGPoint) -> Void)?
public var moved: ((CGPoint) -> Void)?
public var ended: ((CGPoint, CGPoint?) -> Void)?
private var previousPoints: [(CGPoint, Double)] = []
override public func reset() {
super.reset()
self.previousPoints.removeAll()
}
private func addPoint(_ point: CGPoint) {
self.previousPoints.append((point, CACurrentMediaTime()))
if self.previousPoints.count > 6 {
self.previousPoints.removeFirst()
}
}
private func estimateVerticalVelocity() -> CGFloat {
let timestamp = CACurrentMediaTime()
var sum: CGFloat = 0.0
var count = 0
if self.previousPoints.count > 1 {
for i in 1 ..< self.previousPoints.count {
if self.previousPoints[i].1 >= timestamp - 0.1 {
sum += (self.previousPoints[i].0.y - self.previousPoints[i - 1].0.y) / CGFloat(self.previousPoints[i].1 - self.previousPoints[i - 1].1)
count += 1
}
}
}
if count != 0 {
return sum / CGFloat(count * 5)
} else {
return 0.0
}
}
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
if let touch = touches.first {
let location = touch.location(in: self.view)
self.addPoint(location)
self.began?(location)
}
}
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)
if let touch = touches.first {
let location = touch.location(in: self.view)
self.addPoint(location)
self.moved?(location)
}
}
override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesEnded(touches, with: event)
if let touch = touches.first {
let location = touch.location(in: self.view)
self.addPoint(location)
self.ended?(location, CGPoint(x: 0.0, y: self.estimateVerticalVelocity()))
}
}
override public func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesCancelled(touches, with: event)
if let touch = touches.first {
self.ended?(touch.location(in: self.view), nil)
}
}
}