ロングプレス検出後、押し続けられている間、特定のアクションを呼び出し続けるコーディングを考えます。
環境
OS X: 10.8.5
Xcode: 5.1.1
ロングプレス・ジェスチャーリコグナイザ
xibまたは、storyboardのConnection inspectorから、ロングプレスイベントのアクションを設定することはできません。
UILongPressGestureRecognizerクラスを使って、ロングプレスされたとき呼出するアクションを設定します。
ここでは、self(ViewController)のlongPressアクションを呼び出しています。
初期設定
// プロパティの設定
@property (nonatomic, weak) IBOutlet UIButton *button;
// viewDidLoadなどで
// ジェスチャーリコグナイザの生成
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
// ボタンに設定
[_button addGestureRecognizer:longPress];
ロングプレスの検出時間間隔は、minimumPressDurationプロパティで設定できます。デフォルトは0.5秒です。
longPress.minimumPressDuration = 0.5;
ロングプレスされている間に呼出する処理を記述します。最後にperformSelectorを使って0.5秒に再度自分自身を呼出します。
リピート処理
- (void)repeat:(id)sender
{
// リピート処理を記述
// 0.5秒後に再度呼出
[self performSelector:@selector(repeat:) withObject:nil afterDelay:0.5];
}
ロングプレス検出
ロングプレスが検出されたら、stateがUIGestureRecognizerStateBeganが設定されて一度だけ呼出されます。上記のrepeatメソッドを呼び出します。
このままでは、永遠にrepeatメソッドが呼び続けられるので、stateがUIGestureRecognizerStateEndedになったら、cancelPreviousPerformRequestsWithTargetで繰り返す処理をキャンセルします。
ここでは利用していませんが、ロングタップ中にドラッグするとstateがUIGestureRecognizerStateChanged
に設定されて呼出されます。
- (void)longPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
switch (gestureRecognizer.state) {
case UIGestureRecognizerStateBegan:
[self performSelector:@selector(repeat:) withObject:nil afterDelay:0.5];
break;
case UIGestureRecognizerStateChanged:
break;
case UIGestureRecognizerStateEnded:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(repeat:) object:nil];
break;
default:
break;
}
}
これを利用すれば、ロングプレス時にカウントを連続して増減するような処理が実装できると思います。
もちろん、Touch Up Insideイベントとの併用も可能です。
androidでは、Threadを使ってロングプレス検出とリピート処理を実装していたのですが、iOSでは、ちょっと楽ですね。