Получить исходное местоположение касания из UIPanGestureRecognizer

К моему представлению добавлено UIPanGestureRecognizer.
Проблема в том, что к тому времени, когда касание распознается как жест панорамирования, его нужно переместить на несколько точек, и я не могу извлечь исходное местоположение касания в точке UIGestureRecognizerStateBegan. штат. В этом состоянии translationInView: равно (0,0), и любые последующие ходы рассчитываются с этой точки, а не с исходной.

Есть ли способ извлечь исходное местоположение из самого распознавателя жестов или мне нужно переопределить метод touchesBegan:?


person antalkerekes    schedule 20.09.2011    source источник
comment
Эта ссылка может помочь: icodblog.com/2010/10/14/ работа с распознавателями жестов   -  person Caffeinated    schedule 20.09.2011
comment
это очень просто в наши дни, это просто sender.location(in: self)   -  person Fattie    schedule 17.01.2020


Ответы (4)


Вы должны иметь возможность установить delegate для распознавателя жестов и реализовать

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

чтобы получить первоначальный контакт.

person Sherman Lo    schedule 20.09.2011
comment
Это тоже работает. Однако в конце я использовал touchesBegan:. Похоже, распознаватель жестов панорамирования действительно не знает, где изначально началось событие касания. - person antalkerekes; 22.09.2011

Вы можете решить эту проблему, внедрив пользовательский PanGestureRecognizer, который сохраняет исходную точку касания и делает ее доступной для вызывающего абонента.

Я пошел по этому пути, так как также хотел контролировать расстояние, на которое перемещается, чтобы активировать жест панорамирования.

Это может быть излишним для вашей ситуации, но работает отлично и не так сложно, как кажется.

Чтобы получить координаты точки соприкосновения, вы просто вызываете:

[sender touchPointInView:yourView] 

вместо:

[sender locationInView:yourView]

Вот код для PanGestureRecognizer.m:

#import "PanGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>

@implementation PanGestureRecognizer

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    UITouch *touch = [touches anyObject];

    // touchPoint is defined as: @property (assign,nonatomic) CGPoint touchPoint;

    self.touchPoint = [touch locationInView:nil];   
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:nil];

    // customize the pan distance threshold

    CGFloat dx = fabs(p.x-self.touchPoint.x);
    CGFloat dy = fabs(p.y-self.touchPoint.y);

    if ( dx > 2 || dy > 2)  {
        if (self.state == UIGestureRecognizerStatePossible) {
            [self setState:UIGestureRecognizerStateBegan];
        }
        else {
            [self setState:UIGestureRecognizerStateChanged];
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    if (self.state == UIGestureRecognizerStateChanged) {
        [self setState:UIGestureRecognizerStateEnded];
    }
    else {
        [self setState:UIGestureRecognizerStateCancelled];
    }
}

- (void) reset
{
}

// this returns the original touch point

- (CGPoint) touchPointInView:(UIView *)view
{
    CGPoint p = [view convertPoint:self.touchPoint fromView:nil];

    return p;
}

@end
person northernman    schedule 01.03.2014
comment
Я не понимаю, как это можно использовать. - person Iulian Onofrei; 08.05.2015

Если вы используете locationInView: вместо translationInView:, вы получите абсолютные координаты вместо относительных координат. Однако вам нужно запустить панорамирование, чтобы получить ввод... Чтобы обойти это, ваше представление может быть UIButton, и вы можете вызвать - (IBAction)buttonWasTouched:(UIButton *)button forEvent:(UIEvent *)event, подключенный к "touch down", например:

-(IBAction)shakeIntensityPanGesturebuttonWasTouched:(UIButton *)button forEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:touch.view]; //touch location local cordinates
}
person Andres Canella    schedule 21.08.2012

Вы можете использовать UIGestureRecognizerState

- (void) onPanGesture:(UIPanGestureRecognizer *)sender {
    if(sender.state == UIGestureRecognizerStateBegan) {
        origin = [sender locationInView];
    } else {
        current = [sender locationInView];
        // Initial touch stored in origin
    }
}

Свифт (иш):

var state = recognizer.state
if state == UIGestureRecognizerState.Began {
    println(recognizer.locationInView(viewForGesture))
    //this will be the point of first touch
}
person Aiden    schedule 17.10.2015
comment
Распознаватели жестов имеют разные состояния (.Начало, .Завершено, .Отменено и т. д.). Если вы получите местоположение (просмотр или касание), когда состояние распознавателя равно .Began, у вас будет его первое местоположение. - person Aiden; 21.10.2015
comment
Поместите этот код внутрь функции, которая вызывается жестом. Строка println выше будет печатать только одну пару координат для каждого касания/панорамирования. - person Aiden; 21.10.2015
comment
Переопределение touchesBegan и вывод его значения показывает, что оно не совпадает со значением, возвращаемым locationInView, когда состояние равно .Began. - person par; 06.01.2016