オブジェクト自体を長押ししてゲームオブジェクトの属性を設定するゲームに取り組んでいます。属性の値は、長押しジェスチャの長さによって決まります。私はこの目的のためにUILongPressGestureRecognizerを使用しているので、次のようになります。
[gameObjectView addGestureRecognizer:[[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handle:)]];
次に、ハンドラー関数
- (void)handle:(UILongPressGestureRecognizer)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
// Get the duration of the gesture and calculate the value for the attribute
}
}
この場合、長押しジェスチャの持続時間を取得するにはどうすればよいですか?
ジェスチャには、アクセスできるようにこの情報が保存されていないことは間違いありません。ジェスチャが認識されるまでの時間であるminimumPressDurationと呼ばれるプロパティのみを設定できます。
IOS 5の回避策(未テスト):
TimerというNSTimerプロパティを作成します:@property (nonatomic, strong) NSTimer *timer;
そしてカウンター:@property (nonatomic, strong) int counter;
次に@synthesize
- (void)incrementCounter {
self.counter++;
}
- (void)handle:(UILongPressGestureRecognizer)gesture {
if (gesture.state == UIGestureRecognizerStateBegan) {
self.counter = 0;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(incrementCounter) userInfo:nil repeats:yes];
}
if (gesture.state == UIGestureRecognizerStateEnded) {
[self.timer invalidate];
}
}
したがって、ジェスチャが開始すると、ジェスチャが終了するまで1秒ごとにインクリメントメソッドを起動するタイマーを開始します。この場合、minimumPressDuration
を0に設定する必要があります。そうしないと、ジェスチャーがすぐに開始されません。次に、カウンターでやりたいことを何でもします!
タイマーは必要ありません。あなたはこの方法でそれを達成することができます:
- (void)handleRecognizer:(UILongPressGestureRecognizer *)gesture
{
static NSTimeInterval pressStartTime = 0.0; //This an be moved out and be kept as a property
switch ([gesture state])
{
case UIGestureRecognizerStateBegan:
//Keeping start time...
pressStartTime = [NSDate timeIntervalSinceReferenceDate];
break; /* edit*/
case UIGestureRecognizerStateEnded:
{
//Calculating duration
NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - pressStartTime;
//Note that NSTimeInterval is a double value...
NSLog(@"Duration : %f",duration);
break;
}
default:
break;
}
}
また、長押しの実際の持続時間を取得したい場合は、作成時にジェスチャレコグナイザーのminimumPressDuration
を0
に設定することを忘れないでください。myLongPressGestureRecognizer.minimumPressDuration = 0
オブジェクト指向のCocoaTouchで最もクリーンでシンプルなソリューションは、UILongPressGestureをサブクラス化することだと思われます。これはSwiftで書かれた例です。
class MyLongPressGesture : UILongPressGestureRecognizer {
var startTime : NSDate?
}
func installGestureHandler() {
let longPress = MyLongPressGesture(target: self, action: "longPress:")
button.addGestureRecognizer(longPress)
}
@IBAction func longPress(gesture: MyLongPressGesture) {
if gesture.state == .Began {
gesture.startTime = NSDate()
}
else if gesture.state == .Ended {
let duration = NSDate().timeIntervalSinceDate(gesture.startTime!)
println("duration was \(duration) seconds")
}
}
最初のタップからの時間を含める場合は、gesture.minimumPressDurationを追加して、継続時間を計算するときに含めることができます。欠点は、ジェスチャがトリガーされてから.Startハンドラーが呼び出されるまでにわずかな(わずかな)時間が経過する可能性があるため、おそらくマイクロ秒の精度ではないことです。しかし、問題にならないはずのアプリケーションの大部分では。
「minimumPressDuration」プロパティを参照してください。ドキュメントによると:
ジェスチャが認識されるためには、指がビューを押す必要がある最小期間。
[...]
時間間隔は秒単位です。デフォルトの期間は0.5秒です。
Swift 3.でフォローすることで入手できます
ロジック:押す時間を割り当てて、タッチが終了する時間の差を見つけるだけです
コード:
//variable to calculate the press time
static var pressStartTime: TimeInterval = 0.0
func handleRecognizer(gesture: UILongPressGestureRecognizer) -> Double {
var duration: TimeInterval = 0
switch (gesture.state) {
case .began:
//Keeping start time...
Browser.pressStartTime = NSDate.timeIntervalSinceReferenceDate
case .ended:
//Calculating duration
duration = NSDate.timeIntervalSinceReferenceDate - Browser.pressStartTime
//Note that NSTimeInterval is a double value...
print("Duration : \(duration)")
default:
break;
}
return duration
}
私はこれが遅い答えであることを知っていますが、これはタイマーを作成する必要なしにIOS 7&8で私にとって完全に機能します。
UILongPressGestureRecognizer *longGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(yourAction)]; // create the recognizer
longGR.minimumPressDuration = 10.0f; //Ten Seconds
longGR.allowableMovement = 50.0f; //Allowable Movement while being pressed
[gameObjectView setUserInteractionEnabled:YES]; //If setting interaction to a non-interactable object such as a UIImageView
[gameObjectView addGestureRecognizer:longGR]; //Add the gesture recognizer to your object
新しいiOSバージョン(現時点では10)では、.begin
状態と.ended
状態の両方に対する長押し認識機能のコールバックは、イベントが終了した後にのみ、次々に発生するようです。画面から指を離したときだけです。
そのため、2つのイベントの違いはミリ秒の何分の1かであり、実際に検索していたものではありません。
これが修正されるまで、Swiftで別のジェスチャレコグナイザーを最初から作成することにしました。これがその動作スケルトンになります。
import UIKit.UIGestureRecognizerSubclass
class LongPressDurationGestureRecognizer : UIGestureRecognizer {
private var startTime : Date?
private var _duration = 0.0
public var duration : Double {
get {
return _duration
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
startTime = Date() // now
state = .begin
//state = .possible, if you would like the recongnizer not to fire any callback until it has ended
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
_duration = Date().timeIntervalSince(self.startTime!)
print("duration was \(duration) seconds")
state = .ended
//state = .recognized, if you would like the recongnizer not to fire any callback until it has ended
}
}
次に、LongPressDurationGestureRecognizer
ジェスチャレコグナイザの.duration
プロパティに簡単にアクセスできます。
例えば:
func handleLongPressDuration(_ sender: LongPressDurationGestureRecognizer) {
print(sender.duration)
}
この特定の例では、実際に行われたタッチの数やその場所は考慮されていません。ただし、LongPressDurationGestureRecognizerを拡張して、簡単に試すことができます。