问题 从UIPanGestureRecognizer获取原始触摸位置


我的观点有一个 UIPanGestureRecognizer 添加到它。
问题是,当触摸被识别为平移手势时,它必须被移动几个点,并且我无法提取原始触摸位置 UIGestureRecognizerStateBegan 州。 在这种状态下 translationInView: 是(0,0),并且从这一点开始计算任何后续移动,而不是从原始移动。

有没有办法从手势识别器本身提取原始位置,或者我是否需要覆盖 touchesBegan: 方法?


4310
2017-09-20 01:16


起源

这个链接可能有帮助 - icodeblog.com/2010/10/14/working-with-uigesturerecognizers - Coffee


答案:


你应该能够设置 delegate 用于手势识别器和实现

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

获得初步接触。


7
2017-09-20 02:59



这也有效。但是,最后我用了 touchesBegan:。看起来,平移手势识别器实际上并不知道触摸事件最初开始的位置。 - antalkerekes


您可以通过实现自定义来解决此问题 PanGestureRecognizer 它保存了原始触摸点并使其可供调用者使用。

我走了这条路,因为我也想控制移动的距离来触发a 潘的姿态

这可能对你的情况来说太过分了,但是效果很好而且听起来不那么困难。

要获得接触点坐标,只需调用:

[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

3
2018-03-01 19:27



我不明白应该如何使用它。 - Iulian Onofrei


如果你使用 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
}

1
2017-08-21 15:16





你可以使用 UIGestureRecognizerState 

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

斯威夫特(ish):

var state = recognizer.state
if state == UIGestureRecognizerState.Began {
    println(recognizer.locationInView(viewForGesture))
    //this will be the point of first touch
}

0
2017-10-17 14:53



请为您的答案提供某种解释.. - Lal
手势识别器具有不同的状态(.Began,.Ended,.Cancelled等...)。如果您在识别器状态为时获得(查看或触摸)的位置.Began您将拥有其第一个位置。 - Aiden
将此代码放在手势调用的函数中。上面的println行每个触摸/平移只会打印一个坐标对 - Aiden
重写 touchesBegan 并打印其值表明它与返回的值不同 locationInView 当国家是 .Began。 - par