【问题标题】:Enable UIPanGestureRecognizer when did longPresslongPress 时启用 UIPanGestureRecognizer
【发布时间】:2015-07-12 22:28:42
【问题描述】:

customView 执行longPress 时,我想在customView 上启用UIPanGestureRecognizer
(我希望当你longPresscustomView时,customView会切换到“移动模式”,你可以通过拖动来移动customView。)

但在这段代码中,只有longPressAction: 被调用。 panAction: 没有打电话。
如何修复它以启用PanAction:

- (void)viewDidLoad
{
    [self.view addSubview:customView];

    UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
    [customView addGestureRecognizer:longPressRecognizer];
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
    [customView addGestureRecognizer:panRecognizer];
}

- (void)longPressAction:(UILongPressGestureRecognizer *)recognizer
{
    if ([recognizer state] == UIGestureRecognizerStateBegan) {
        CustomView *customView = (CustomView *)recognizer.view;
        customView.panRecongnizerEnabled = YES; //panRecongnizerEnabled is CustomView's property
    }
    if ([recognizer state] == UIGestureRecognizerStateEnded) {
        CustomView *customView = (CustomView *)recognizer.view;
        customView.panRecongnizerEnabled = NO;
    }
}

- (void)panAction:(UIPanGestureRecognizer *)recognizer
{
    CustomView *customView = (CustomView *)recognizer.view;
    if (customCell.panRecongnizerEnabled == NO) return;
    NSLog(@"running panAction");
}

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

【问题讨论】:

  • 老实说,听起来您应该在长按后在 UIView 本身上监听 touchesBegan/touchesMoved/touchesEnded,这样您就可以设置锁定边界并适当地移动视图。

标签: ios objective-c uigesturerecognizer


【解决方案1】:

您的 ViewController 需要符合 UIGestureRecognizerDelegate。我怀疑你要么已经这样做了 要么 否则 shouldRecognizeSimultaneouslyWithGestureRecognizer 将没有任何意义。但是您绝对缺少的是将gestureRecognizer 的委托设置为您的视图控制器:

longPressRecognizer.delegate = self;
panRecognizer.delegate = self;

现在您应该同时收到长按和平移。

注意: 我在没有任何 customView 的情况下进行了测试,只是将它们添加到 self.view。至少在这种情况下,上面的代码按预期工作。

【讨论】:

  • 这帮助我弄清楚为什么 shouldRecognizeSimultaneouslyWithGestureRecognizer 和 gestureRecognizerShouldBegin 没有触发。谢谢!
  • 这太棒了! UILongPressGestureRecognizer 不再阻止滚动。
【解决方案2】:

我知道这个问题已经关闭了一段时间,但我最近不得不做类似的事情,并且有一个更清洁的解决方案。 UILongPressGestureRecognizer 是您执行此操作所需的全部内容。

长按手势是连续的。手势开始 (UIGestureRecognizerStateBegan) 当允许的手指数 (numberOfTouchesRequired) 已按指定时间段 (minimumPressDuration) 并且触摸不会超出 允许的移动范围(allowableMovement)。手势 每当手指移动时,识别器都会转换到 Change 状态, 并且它在任何手指时结束(UIGestureRecognizerStateEnded) 被提升了。

因此,对于您所需要的,不需要UIPanGestureRecognizer。只需添加 UILongPressGestureRecognizer 并将其附加到您的主视图。

- (void)viewDidLoad {
    [super viewDidLoad];

    UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
    // set this to your desired delay before the pan action will start.
    longPressRecognizer.minimumPressDuration = 0.5; 
    [self.view addGestureRecognizer:longPressRecognizer];
}

然后,实现 longPressAction 方法,不仅查看UIGestureRecognizerStateBeganUIGestureRecognizerStateEnded 状态,还查看UIGestureRecognizerStateChanged 状态:

- (void)longPressAction:(UIGestureRecognizer *)recognizer
{
    if ([recognizer state] == UIGestureRecognizerStateBegan || [recognizer state] == UIGestureRecognizerStateChanged ) {
        CGPoint touchPoint =  [recognizer locationInView:self.view];
        [self.viewToMove setCenter: touchPoint];
        NSLog(@"running panAction");
    }
}

在我的示例中,我只是移动了一个虚拟视图来跟踪用户手指的中心,但是您可以将任何您可以放入 UIPanGestureRecognizer 的代码中的逻辑。只需将它放在 if 块中,它就会大大简化您的代码,并且您不需要处理两个手势识别器之间的交互。当用户只是在屏幕上移动手指(但没有长按)时,您的代码还会导致对 panAction 方法的许多不必要的调用。

【讨论】:

    【解决方案3】:

    您可以通过在长按后启用平移来做到这一点。无论如何,您必须保存一个标志才能知道是否调用了 longPress。为了在长按后启用平移手势,您可以使用平移手势委托,如下所示:

    let previewLongPress = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressed(sender:)))
    let previewPanGesture = UIPanGestureRecognizer(target: self, action: #selector(onPanGesture(sender:)))
    
    previewPanGesture?.delegate = self
    

    你的委托应该是这样的:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return gestureRecognizer == previewPanGesture && otherGestureRecognizer == previewLongPress
    }
    

    现在您可以在长按手势后进行平移手势。

    希望它可以帮助其他人。

    【讨论】:

    • 有没有办法以无缝的方式做到这一点?我希望用户能够使用 UIPanGestureRecognizer 长按并开始以单个动作平移视图(而不是必须点击然后点击并按住才能开始平移)。有关我在做什么的详细信息,请参见此处:stackoverflow.com/questions/68663562/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多