UIViewがタッチダウンされ、UIViewがタップされていることを検出する方法を決定する問題で立ち往生しています。タッチダウンしたら、UIViewの背景色を変更します。触れられたら、UIViewに特定のタスクを実行させたいです。この問題を解決する方法を知りたいです。
-(void)viewDidLoad
{
UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)];
dismissGestureRecognition.numberOfTapsRequired = 1;
[sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition];
UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)];
dismissGestureRecognition.numberOfTouchesRequired = 1;
[sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition];
}
- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap {
SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil];
[self.navigationController pushViewController:settingsDouble animated:YES];
}
- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap {
NSLog(@"Down");
}
Gesture Recognizerは、おそらくあなたが望むものに対してはやりすぎです。おそらく、-touchesBegan:withEvent:
と-touchesEnded:withEvent:
の組み合わせを使用するだけです。
これには欠陥がありますが、それはあなたに何をしたいのかというアイデアを与えるはずです。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.touchDown = YES;
self.backgroundColor = [UIColor redColor];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered when touch is released
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered if touch leaves view
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}
このコードは、作成したUIView
のカスタムサブクラスに配置する必要があります。次に、UIView
の代わりにこのカスタムビュータイプを使用すると、タッチ処理が行われます。
このメソッドはサブクラス化を必要としません。 UILongPressGestureRecognizer
をビューに追加し、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
func tapHandler(gesture: UITapGestureRecognizer) {
// handle touch down and touch up events separately
if gesture.state == .Began {
myView.backgroundColor = UIColor.darkGrayColor()
} else if gesture.state == .Ended {
myView.backgroundColor = UIColor.lightGrayColor()
}
}
}
この回答 のアイデアに感謝します。
すべてのUIControlサブクラス(UIButtonなど)で、これを使用してUIControlEventの特定のセットをサブスクライブできます。
addTarget:action:forControlEvents
UIControlEventTouchDownの適切なセレクターとUIControlEventTouchUpInsideイベントの別のターゲット/セレクターでターゲットを追加する必要があります。
Holly's answer のおかげで、ButtonView
コンビニエンスクラスを作成しました。
編集: answer のとおり、UILongPressGestureRecognizer
は非常に高速に反応するため、クラスを更新しました。
使用法:
let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called
クラス:
/** View that can be pressed like a button */
import UIKit
class ButtonView : UIView {
/* Called when the view goes to normal state (set desired appearance) */
var onNormal = {}
/* Called when the view goes to pressed state (set desired appearance) */
var onPressed = {}
/* Called when the view is released (perform desired action) */
var onReleased = {}
override init(frame: CGRect)
{
super.init(frame: frame)
let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:"))
recognizer.delegate = self
recognizer.minimumPressDuration = 0.0
addGestureRecognizer(recognizer)
userInteractionEnabled = true
onNormal()
}
func touched(sender: UILongPressGestureRecognizer)
{
if sender.state == .Began {
onPressed(self)
} else if sender.state == .Ended {
onNormal(self)
onReleased()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
まず、セレクターによってhandleDismissDoubleTap:
、ダブルタップを解除するのを探していると思います。これを実現するには、次のことを行う必要があります。dismissGestureRecognition.numberOfTapsRequired = 2;
第二に、タッチダウンが長時間のタップ(または「タップアンドホールド」)のようなジェスチャーを意味する場合、UILongPressGestureRecognizer
の代わりにUITapGestureRecognizer
を使用する必要があります。