试图使UITableViewCell可滑动和可点击,同时保持UITableView可滚动,为什么我的单元格滑动有时只能工作?

Dou*_*ith 3 objective-c uitableview uigesturerecognizer ios uipangesturerecognizer

我有一个UITableView,其单元格是UITableViewCell的子类,它有一个顶部UIView和一个底部UIView,允许顶部UIView在用户拖动他/她的手指时向右和向左移动.

我通过向每个UITableViewCell添加一个平移手势识别器来实现它.很简单的东西.但是我只想要水平平底锅,但是当它打算向上滚动时会检测到整个单元格的垂直平底锅,这会导致UITableView无法移动.

我试图这样做,只有当用户水平摇动他/她的手指超过5px时才会检测到手势,但它似乎没有工作.滚动工作正常,我可以点击单元格,但我在单元格上滑动十次,它可能工作一次.

我无法弄清楚为什么.

相关代码:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer {
    if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        NSLog(@"hi");
        CGPoint translation = [(UIPanGestureRecognizer *)recognizer translationInView:self];

        if (translation.x > 5 || translation.x < -5) {
            return YES;
        }
        else {
            return NO;
        }
    }
    else {
        return YES;
    }
}

- (void)pannedCell:(UIPanGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        _firstTouchPoint = [recognizer translationInView:self];
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged) {
        CGPoint touchPoint = [recognizer translationInView:self];

        // Holds the value of how far away from the first touch the finger has moved
        CGFloat xPos;

        // If the first touch point is left of the current point, it means the user is moving their finger right and the cell must move right
        if (_firstTouchPoint.x < touchPoint.x) {
            xPos = touchPoint.x - _firstTouchPoint.x;

            if (xPos <= 0) {
                xPos = 0;
            }
        }
        else {
            xPos = -(_firstTouchPoint.x - touchPoint.x);

            if (xPos >= 0) {
                xPos = 0;
            }
        }

        if (xPos > 10 || xPos < -10) {
            // Change our cellFront's origin to the xPos we defined
            CGRect frame = self.cellFront.frame;
            frame.origin = CGPointMake(xPos, 0);
            self.cellFront.frame = frame;
        }
    }
    else if (recognizer.state == UIGestureRecognizerStateEnded) {
        [self springBack];
    }
    else if (recognizer.state == UIGestureRecognizerStateCancelled) {
        [self springBack];
    }
}
Run Code Online (Sandbox Code Playgroud)

我究竟应该做些什么来使这个实现更好地工作?

dc.*_*dc. 11

这样做的一个好方法是在你移动某个值时只是开始平移而不搞乱是确定手势识别器在哪个方向上转换最多并使用它.它减少了你需要的代码量,并且在我的测试中运行得相当好.

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        CGPoint translation = [(UIPanGestureRecognizer*)gestureRecognizer translationInView:self.superview];
        return fabsf(translation.x) > fabsf(translation.y)
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

现在你的视图滑动变得更简单了.此代码允许您向任一方向拖动.

- (void)drag:(UIPanGestureRecognizer *)sender {
    CGPoint translation = [sender translationInView:self.superview];
    CGRect frame = self.upperView.frame;

    switch (sender.state) {
        case UIGestureRecognizerStateChanged:
            frame.origin.x = translation.x;
            [self.upperView setFrame:frame];
            break;
        case UIGestureRecognizerStateBegan:
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateFailed:
        default:
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,您可能希望允许您的手势识别器与其他人一起工作(例如,处理表视图滚动的识别器),但代码中的代码gestureRecognizerShouldBegin:似乎没有问题.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

另请注意,我正在使用self.superview而不是self像您一样.这是因为translationInView:文档部分中的这一行:

应该在其坐标系中计算平移手势的平移的视图.如果要调整视图的位置以将其保留在用户手指下,请在该视图的超视图坐标系中请求翻译.