Я пытаюсь создать UIPinchGestureRecognizer, который терпит неудачу, если пользователь зажимает (перемещает пальцы). Я знаю, что есть очень простой способ сделать это, просто используя масштаб распознавателя в методе действий, и если он больше 1, установите флаг и проигнорируйте все будущие вызовы. Тем не менее, это не работает для меня, у меня есть другие распознаватели жестов, которые требуют, чтобы этот распознаватель пинча терпел неудачу, поэтому мне нужно, чтобы он неправильно срабатывал, когда пользователь зажимает неправильное направление.UIPinchGestureRecognizer только для стягивания
Я попытался подкласс UIPinchGestureRecognizer:
@implementation BHDetailPinchGestureRecogniser {
CGFloat initialDistance;
}
#pragma mark - Object Lifecycle Methods
- (id)initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
initialDistance = NSNotFound;
}
return self;
}
#pragma mark - UIGestureRecogniser Methods
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)recogniser {
if ([recogniser isKindOfClass:[UIPinchGestureRecognizer class]]) {
return [self.delegate gestureRecognizerShouldBegin:self];
} else return false;
}
- (void)reset {
[super reset];
initialDistance = NSNotFound;
}
#pragma mark - Touch Handling Methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (touches.count >= 2) {
if (self.state == UIGestureRecognizerStatePossible) {
// Keep hold of the distance between the touches
NSArray *bothTouches = [touches allObjects];
CGPoint location1 = [(UITouch *)bothTouches[0] locationInView:self.view];
CGPoint location2 = [(UITouch *)bothTouches[1] locationInView:self.view];
initialDistance = [self distanceBetweenPoint:location1 andPoint:location2];
}
} else {
// Fail if there is only one touch
self.state = UIGestureRecognizerStateFailed;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"Moved. (tc, %lu) (state, %i) (id, %f)", (unsigned long)touches.count, self.state, initialDistance);
if (touches.count >= 2) {
if (self.state == UIGestureRecognizerStatePossible) {
if (initialDistance != NSNotFound) {
// Get the new distance and see if is is larger or smaller than the original
NSArray *bothTouches = [touches allObjects];
CGPoint location1 = [(UITouch *)bothTouches[0] locationInView:self.view];
CGPoint location2 = [(UITouch *)bothTouches[1] locationInView:self.view];
NSLog(@"Checking distance between points.");
if ([self distanceBetweenPoint:location1 andPoint:location2] < initialDistance - 3.f) {
NSLog(@"Began");
self.state = UIGestureRecognizerStateBegan;
} else if ([self distanceBetweenPoint:location1 andPoint:location2] > initialDistance) {
NSLog(@"Failed");
self.state = UIGestureRecognizerStateFailed;
}
}
} else {
self.state = UIGestureRecognizerStateChanged;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.state == UIGestureRecognizerStatePossible) self.state = UIGestureRecognizerStateFailed;
else [super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
self.state = UIGestureRecognizerStateCancelled;
}
#pragma mark - Helper Methods
- (CGFloat)distanceBetweenPoint:(CGPoint)point1 andPoint:(CGPoint)point2 {
return sqrtf(powf(point1.x - point2.x, 2) + powf(point1.y - point2.y, 2));
}
@end
То, что я понял, что это не так просто, нужно будет обрабатывать несколько прикосновений, иногда прикасается перемещается только имеет одно касание, так что нужно будет держать прикосновение касания, одно касание может закончиться и другое начало, и это все еще хочет быть частью пинча. Похоже, что я теряю встроенную функциональность распознавателя пинча, когда все, что я хочу сделать, это сделать его неудачным, если пользователь зажимает неправильное направление.
Есть ли более простой способ добиться такого поведения без полного перезаписи UIPinchGestureRecognizer? Вероятно, стоит упомянуть, что у меня нет контроля над другими распознавателями, которых я хочу потерпеть неудачу (они глубоко в чашках PSPDFViewController (сторонняя библиотека)).
Я дам ему идти! Я думал, что в момент, когда этот метод делегата называется так называемым шкалой, будет 1 или какое-то неопределенное значение ... Всего в секунду ... –
Масштаб установлен, хотя это не приведет к сбою вашего жеста, «начать». Возможно, вы сможете добавить код, чтобы он сработал. –
Это работает отлично! Спасибо! Такое простое и изящное решение. Кажется, мне это не нужно, я просто нуждаюсь в этом, чтобы не признать. –