如何让UIGestureRecognizer识别后失败?

发布于 2024-12-03 13:33:41 字数 646 浏览 0 评论 0原文

我有一个看似基本但无法弄清楚的问题。

基本问题是:当手势识别器处于 UIGestureRecognizerStateBegan 或 UIGestureRecognizerStateChanged 状态时,如何以编程方式将手势识别器从处理程序置于失败状态?

更详细的解释:我在 UIScrollView 中有一个用于 UIView 的长按手势识别器。我已经这样做了

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

,因为否则一旦用户将手指放在视图上,我就无法让滚动视图滚动。这是像 Safari 一样的基本触摸,您将手指放在链接上,该链接会突出显示,但向上或向下滚动 - 然后链接不会突出显示并且滚动视图会移动。

我现在可以大部分工作,因为两个手势都被识别,但如果我可以检测长按手势识别器的 StateChanged 中的移动,并且如果它超过 20 像素左右,只需以编程方式使长按失败,那就更好了。

这可以吗?或者我挖错地方了?

I have a question that might seem basic but can't figure it out.

Basic question is: how do I programmatically put a gesturerecognizer into fail state from handler, while it's in UIGestureRecognizerStateBegan or UIGestureRecognizerStateChanged?

More detailed explanation: I have a long press gesture recognizer for UIView inside a UIScrollView. I have made

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

because else I can't get scroll view to scroll once user puts their finger down at the view. It's basic touch like safari, where you hold finger down on a link, which highlights the link, but scroll up or down - then link is unhighlighted and scrollview moves.

I can get this mostly working right now since both gestures are being recognized, but it would be better if I can detect movement in longpress gesturerecognizer's StateChanged, and if it's more than 20 pixels or so, just programmatically make longpress fail.

Is this possible to do? Or am I digging at a wrong spot?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你另情深 2024-12-10 13:33:41

我在发布问题后发现的另一个问题..

这是我现在在手势识别器处理程序中所做的操作:

else if (sender.state == UIGestureRecognizerStateChanged) {
    CGPoint newTouchPoint = [sender locationInView:[self superview]];

    CGFloat dx = newTouchPoint.x - initTouchPoint.x;
    CGFloat dy = newTouchPoint.y - initTouchPoint.y;
    if (sqrt(dx*dx + dy*dy) > 25.0) {
        sender.enabled = NO;
        sender.enabled = YES;
    }
}

因此,如果手指在任何方向上移动超过 25 个像素,将启用属性设置为“否”将使识别器失败。所以这将实现我想要的!

Another question that I found right after I posted the question..

Here's what I do in the gesture recognizer handler now:

else if (sender.state == UIGestureRecognizerStateChanged) {
    CGPoint newTouchPoint = [sender locationInView:[self superview]];

    CGFloat dx = newTouchPoint.x - initTouchPoint.x;
    CGFloat dy = newTouchPoint.y - initTouchPoint.y;
    if (sqrt(dx*dx + dy*dy) > 25.0) {
        sender.enabled = NO;
        sender.enabled = YES;
    }
}

So if finger moves more than 25 pixels in any direction, setting enabled property to NO will make the recognizer fail. So this will accomplish what I want!

马蹄踏│碎落叶 2024-12-10 13:33:41

如果是 UILongPressGestureRecognizer,只需设置其 allowableMovement 属性即可。

UILongPressGestureRecognizer* recognizer = [your recognizer];
recognizer.allowableMovement = 25.0f;

If it is a UILongPressGestureRecognizer, just set its allowableMovement property.

UILongPressGestureRecognizer* recognizer = [your recognizer];
recognizer.allowableMovement = 25.0f;
我恋#小黄人 2024-12-10 13:33:41

根据文档,您可以对手势识别器进行子类化:

在 YourPanGestureRecognizer.m 中:

#import "YourPanGestureRecognizer.h"

@implementation YourPanGestureRecognizer

- (void) cancelGesture {
    self.state=UIGestureRecognizerStateCancelled;
}

@end

在 YourPanGestureRecognizer.h 中:

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

@interface NPPanGestureRecognizer: UIPanGestureRecognizer

- (void) cancelGesture;

@end

现在您可以从任何地方调用

YourPanGestureRecognizer *panRecognizer = [[YourPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMoved:)];
[self.view addGestureRecognizer:panRecognizer];
[...]
-(void) panMoved:(YourPanGestureRecognizer*)sender {
    [sender cancelGesture]; // This will be called twice
}

Ref:https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc

According to the documentation you can subclass you gesture recogniser:

In YourPanGestureRecognizer.m:

#import "YourPanGestureRecognizer.h"

@implementation YourPanGestureRecognizer

- (void) cancelGesture {
    self.state=UIGestureRecognizerStateCancelled;
}

@end

In YourPanGestureRecognizer.h:

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

@interface NPPanGestureRecognizer: UIPanGestureRecognizer

- (void) cancelGesture;

@end

Now you can call if from anywhere

YourPanGestureRecognizer *panRecognizer = [[YourPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMoved:)];
[self.view addGestureRecognizer:panRecognizer];
[...]
-(void) panMoved:(YourPanGestureRecognizer*)sender {
    [sender cancelGesture]; // This will be called twice
}

Ref: https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文