こちらも必要に迫られたので作りました。
こちらと合わせてご確認ください。
あと最初ハマったのでこちらも参照ください。
http://qiita.com/okitsutakatomo/items/37e717f2b34a957cca8f
//
// UIHuttobasuGestureRecognizer.swift
//
// Created by Takatomo Okitsu on 2014/12/25.
// Copyright (c) 2014年 Takatomo Okitsu. All rights reserved.
//
import UIKit
var kHuttobasuGestureReturnDistance:CGFloat = 20
class UIHuttobasuGestureRecognizer :UIGestureRecognizer {
var timeOutTimer:NSTimer?
var longTapTimer:NSTimer?
var startingPoint:CGPoint?
var longTapped:Bool = false
override func reset() {
startingPoint = nil
longTapped = false
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.invalidateTimer()
if touches.count > 1 {
self.state = UIGestureRecognizerState.Failed
} else {
let touch:UITouch = touches.anyObject()? as UITouch
if touch.tapCount > 1 {
self.state = .Failed
} else {
longTapTimer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "handleLongTapped", userInfo: nil, repeats: false)
timeOutTimer = NSTimer.scheduledTimerWithTimeInterval(0.8, target: self, selector: "handleTimeOut", userInfo: nil, repeats: false)
return
}
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
let touch:UITouch = touches.anyObject()? as UITouch
if self.state == .Possible {
if self.longTapped {
if startingPoint == nil {
startingPoint = touch.locationInView(nil)
} else {
let point = touch.locationInView(nil)
let distance = (point - startingPoint!).length
if distance > kHuttobasuGestureReturnDistance {
self.state = UIGestureRecognizerState.Ended //event fired
}
}
}
} else {
self.state = .Failed
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
self.invalidateTimer()
self.state = .Failed
}
override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
self.invalidateTimer()
self.state = .Cancelled
}
func invalidateTimer() {
timeOutTimer?.invalidate()
timeOutTimer = nil
longTapTimer?.invalidate()
longTapTimer = nil
}
func handleTimeOut() {
self.invalidateTimer()
self.state = .Failed
}
func handleLongTapped() {
self.longTapped = true
}
}