IOS: Как получить длительность долгого жестжа?

Я работаю над игрой, в которой атрибут игрового объекта задается длительным нажатием на сам объект. Значение атрибута определяется продолжительностью длинного жестов в прессе. Для этого я использую 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
  }
}

Как получить длительность длинного жестов в этом случае?

Ответы

Ответ 1

Я уверен, что жест не хранит эту информацию для вас. Вы можете установить только свойство на нем, называемое minimumPressDuration, которое представляет собой количество времени до распознавания жестов.

Обходной путь с ios 5 (непроверенный):

Создайте свойство 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];
    }
}

Итак, когда этот жест начинается, запускается таймер, который каждую секунду запускает метод инкрементации до тех пор, пока не закончится жест. В этом случае вам нужно установить minimumPressDuration в 0, иначе жест не начнется сразу. Затем сделайте все, что хотите, с помощью счетчика!

Ответ 2

Нет необходимости в таймерах. Вы можете достичь этого следующим образом:

- (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

Ответ 3

Похоже, что самое чистое и простое решение в объектно-ориентированном Cocoa Touch - это подкласс 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. Но для подавляющего большинства приложений это не имеет значения.

Ответ 4

См. свойство minimumPressDuration. Согласно документации:

Пальцы минимального периода должны нажимать на вид для быть признанным.

[...]

Интервал времени находится в секундах. Продолжительность по умолчанию - 0,5 секунд.

Ответ 5

Я знаю, что это поздний ответ, но это отлично работает для меня в 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

Ответ 6

Вы можете получить его, указав в Swift 3.0

Логика: Просто назначьте время нажатия и найдите разницу во времени при касании

Код:

//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
}