在UITableView中检测水平平移

Eri*_*k S 31 iphone cocoa-touch objective-c uitableview uigesturerecognizer

我正在使用UIPanGestureRecognizer来识别UITableView中的水平滑动(准确地说在单元格上,尽管它被添加到表本身).然而,这个手势识别器显然从表中窃取了触摸.我已经有了pangesturerecognizer来识别水平滑动,然后对齐; 但是如果用户通过垂直滑动开始,它应该将该触摸的所有事件传递给tableview.

我尝试过的一件事是禁用识别器,但它不会滚动直到下一个触摸事件.所以我需要它立即通过该活动.

我尝试的另一件事就是让它自己滚动,但是在停止触摸后你会错过持久的速度.

下面是一些代码:

//In the viewdidload method
UIPanGestureRecognizer *slideRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(sliding:)];
[myTable addGestureRecognizer:slideRecognizer];



-(void)sliding:(UIPanGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
    CGPoint translation = [recognizer translationInView:favoritesTable];
    if (sqrt(translation.x*translation.x)/sqrt(translation.y*translation.y)>1) {
        horizontalScrolling = YES; //BOOL declared in the header file
        NSLog(@"horizontal");
        //And some code to determine what cell is being scrolled:
        CGPoint slideLocation = [recognizer locationInView:myTable];
        slidingCell = [myTable indexPathForRowAtPoint:slideLocation];
        if (slidingCell.row == 0) {
            slidingCell = nil;
        }

    }
    else
    {
        NSLog(@"cancel");
    }

    if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled)
    {
    horizontalScrolling = NO;
    }


    if (horizontalScrolling)
    {
        //Perform some code
    }
    else
    {
    //Maybe pass the touch from here; It's panning vertically
    }

}
Run Code Online (Sandbox Code Playgroud)

那么,关于如何通过触摸的任何建议?

另外:我还想过可能是tableview的手势识别器方法的子类,首先检查它是否是水平的; 然而,那么我需要原始代码,我想...不知道Apple是否会遇到问题.另外:我没有继承UITableView(控制器),只是细胞.这段代码在viewcontroller中,它保存了表;)

Flo*_*lke 57

我遇到了同样的问题,并提出了一个与UIPanGestureRecognizer一起使用的解决方案.

与Erik相比,我已经将UIPanGestureRecognizer直接添加到单元格中,因为我只需要一个特定的单元格来支持平移.但我想这也适用于Erik的情况.

这是代码.

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
    UIView *cell = [gestureRecognizer view];
    CGPoint translation = [gestureRecognizer translationInView:[cell superview]];

    // Check for horizontal gesture
    if (fabsf(translation.x) > fabsf(translation.y))
    {
        return YES;
    }

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

水平手势的计算是从Erik的代码中复制的 - 我已经使用iOS 4.3进行了测试.

编辑: 我发现此实现阻止了"滑动到删除"手势.为了重新获得这种行为,我已经在上面的if语句中添加了检查手势的速度.

if ([gestureRecognizer velocityInView:cell].x < 600 && sqrt(translate...
Run Code Online (Sandbox Code Playgroud)

在我的设备上玩了一下后,我想出了500到600的速度,在我看来,它提供了平移和滑动到删除手势之间转换的最佳用户体验.

  • 您可以简化`sqrt(translation.x*translation.x)`;) (5认同)
  • 实际上没有将手势传递给父视图.它将UIGestureRecognizer的状态设置为UIGestureRecognizerStateFailed.结果,父视图然后能够处理手势.这就是我认为它是如何工作的,但我不知道这在技术上是否正确. (2认同)

Tha*_*all 7

我的答案与Florian Mielke的答案相同,但我已经简化并纠正了一些.

如何使用:

只需给你UIPanGestureRecognizer一个代表(UIGestureRecognizerDelegate).例如:

UIPanGestureRecognizer *panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panDetected:)];
panner.delegate = self;
[self addGestureRecognizer:panner];
Run Code Online (Sandbox Code Playgroud)

然后让该委托实现以下方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:gestureRecognizer.view.superview];
    return fabsf(translation.x) > fabsf(translation.y);
}
Run Code Online (Sandbox Code Playgroud)