largetitletextattributes - iOS: ¿Cómo obtener la duración del gesto de pulsación larga?
preferslargetitles (7)
Consulte la propiedad "minimumPressDuration". Según la documentación:
El período mínimo de los dedos debe presionar en la vista para que el gesto sea reconocido.
[...]
El intervalo de tiempo es en segundos. La duración predeterminada es de 0,5 segundos.
Estoy trabajando en un juego en el que un atributo de un objeto de juego se establece presionando prolongadamente el objeto en sí. El valor del atributo está determinado por la duración del gesto de pulsación larga. Estoy usando UILongPressGestureRecognizer para este propósito, así que es algo como esto:
[gameObjectView addGestureRecognizer:[[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handle:)]];
Entonces la función manejadora
- (void)handle:(UILongPressGestureRecognizer)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
// Get the duration of the gesture and calculate the value for the attribute
}
}
¿Cómo obtengo la duración del gesto de pulsación larga en este caso?
Estoy bastante seguro de que el gesto no almacena esta información para que usted acceda. Solo puede establecer una propiedad en ella llamada minimumPressDuration que es la cantidad de tiempo antes de que se reconozca el gesto.
Solución con ios 5 (no probado):
Cree una propiedad de NSTimer llamada timer: @property (nonatomic, strong) NSTimer *timer;
Y un contador: @property (nonatomic, strong) int counter;
Entonces @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];
}
}
Entonces, cuando el gesto comienza, comienza un temporizador que dispara el método de incremento cada segundo hasta que finaliza el gesto. En este caso, querrá establecer la minimumPressDuration
de minimumPressDuration
en 0, de lo contrario, el gesto no comenzará de inmediato. Entonces haz lo que quieras con contador!
No hay temporizadores necesarios. Puedes lograrlo de esta manera:
- (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;
}
}
Además, no olvide establecer la valor minimumPressDuration
de minimumPressDuration
del reconocedor de minimumPressDuration
en 0
mientras lo crea, si desea obtener la duración real de la pulsación larga:
myLongPressGestureRecognizer.minimumPressDuration = 0
Parece que con las nuevas versiones de iOS (10 para mí en este momento), las devoluciones de llamada de reconocimiento de pulsación prolongada para los estados. Dedo de la pantalla.
Eso hace que la diferencia entre los dos eventos sean fracciones de milisegundos, y no lo que realmente estaba buscando.
Hasta que esto se solucione, decidí crear otro reconocedor de gestos desde cero en forma rápida, y ese sería su esquema de trabajo.
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
}
}
Luego, puede acceder a la propiedad LongPressDurationGestureRecognizer
reconocedor de gestos LongPressDurationGestureRecognizer
fácilmente.
Por ejemplo:
func handleLongPressDuration(_ sender: LongPressDurationGestureRecognizer) {
print(sender.duration)
}
Este ejemplo específico, no toma en cuenta cuántos toques tuvieron lugar realmente, o su ubicación. Pero puedes jugar fácilmente con él, extendiendo LongPressDurationGestureRecognizer.
Parece que la solución más simple y limpia en Cocoa Touch orientada a objetos es subclase UILongPressGesture. Aquí hay un ejemplo escrito en 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")
}
}
Si desea incluir el tiempo desde el primer toque, puede incluirlo cuando calcula la duración, agregando de nuevo gesto.minimumPressDuration. El inconveniente es que probablemente no sea preciso en microsegundos, dado que es probable que transcurra una pequeña (pequeña) cantidad de tiempo entre el gesto que se está activando y la llamada del controlador .Start. Pero para la gran mayoría de las aplicaciones eso no debería importar.
Puedes obtenerlo siguiendo en Swift 3.0
Lógica: solo asignando el tiempo de prensa y encuentra la diferencia de tiempo cuando finaliza el toque
Código:
//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
}
Sé que esta es una respuesta tardía, pero funciona perfectamente para mí en iOS 7 y 8 sin tener que crear un temporizador.
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