私がタップイベントを使用しているのは非常に時間に敏感なので、ユーザーがタッチアップすることを要求するのではなく、単にタッチダウンしたときにUITapGestureRecognizerをアクティブにできるかどうか興味がありますか?
カスタムTouchDownGestureRecognizerサブクラスを作成し、touchesでジェスチャーを実装します
TouchDownGestureRecognizer.h
#import <UIKit/UIKit.h>
@interface TouchDownGestureRecognizer : UIGestureRecognizer
@end
TouchDownGestureRecognizer.m
#import "TouchDownGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
@implementation TouchDownGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateRecognized;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
self.state = UIGestureRecognizerStateFailed;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
self.state = UIGestureRecognizerStateFailed;
}
@end
実装:
#import "TouchDownGestureRecognizer.h"
TouchDownGestureRecognizer *touchDown = [[TouchDownGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouchDown:)];
[yourView addGestureRecognizer:touchDown];
-(void)handleTouchDown:(TouchDownGestureRecognizer *)touchDown{
NSLog(@"Down");
}
迅速な実装:
import UIKit
import UIKit.UIGestureRecognizerSubclass
class TouchDownGestureRecognizer: UIGestureRecognizer
{
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
{
if self.state == .Possible
{
self.state = .Recognized
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent)
{
self.state = .Failed
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent)
{
self.state = .Failed
}
}
以下はSwift 2017の貼り付け構文です:
import UIKit.UIGestureRecognizerSubclass
class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
if self.state == .possible {
self.state = .recognized
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
}
これはUITap
のドロップイン置換であることに注意してください。のようなコードで...
func add(tap v:UIView, _ action:Selector) {
let t = UITapGestureRecognizer(target: self, action: action)
v.addGestureRecognizer(t)
}
安全に交換できます。
func add(hairtriggerTap v:UIView, _ action:Selector) {
let t = SingleTouchDownGestureRecognizer(target: self, action: action)
v.addGestureRecognizer(t)
}
テストでは、2回以上呼び出されないことが示されています。ドロップインの代替として機能します。 2つの呼び出しを切り替えることができます。
UILongPressGestureRecognizerを使用して、そのminimumPressDuration
を0に設定します。これは、UIGestureRecognizerStateBegan
状態の間にタッチダウンのように動作します。
func setupTap() {
let touchDown = UILongPressGestureRecognizer(target:self, action: #selector(didTouchDown))
touchDown.minimumPressDuration = 0
view.addGestureRecognizer(touchDown)
}
@objc func didTouchDown(gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
doSomething()
}
}
例:
-(void)setupLongPress
{
self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPress:)];
self.longPress.minimumPressDuration = 0;
[self.view addGestureRecognizer:self.longPress];
}
-(void)didLongPress:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan){
[self doSomething];
}
}
Swift Rob CarawayのObjective-Cの回答 と同様のバージョンです。
アイデアは、タップジェスチャレコグナイザーを使用するのではなく、minimumPressDuration
をゼロに設定した長押しジェスチャレコグナイザーを使用することです。これは、長押しジェスチャレコグナイザがタッチ開始イベントを報告するのに対し、タップジェスチャはそうではないためです。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Add "long" press gesture recognizer
let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
tap.minimumPressDuration = 0
myView.addGestureRecognizer(tap)
}
// called by gesture recognizer
@objc func tapHandler(gesture: UITapGestureRecognizer) {
// handle touch down and touch up events separately
if gesture.state == .began {
// do something...
print("tap down")
} else if gesture.state == .ended { // optional for touch up event catching
// do something else...
print("tap up")
}
}
}
これは別の解決策です。 UIControlのサブクラスを作成します。 UIControlはUIViewのサブクラスであるため、ストーリーボードでもUIViewのように使用できます。
class TouchHandlingView: UIControl {
}
それにaddTarget:
@IBOutlet weak var mainView: TouchHandlingView!
...
mainView.addTarget(self, action: "startAction:", forControlEvents: .TouchDown)
...
次に、指定されたアクションがUIButtonのように呼び出されます。
func startAction(sender: AnyObject) {
print("start")
}