将垂直滚动手势传递到下面的UITableView

时间:2012-10-18 17:35:07

标签: iphone objective-c ios uitableview uigesturerecognizer

(为清晰起见而编辑)

我有一个UITableView。最重要的是附有Pan手势的UIView。此Pan向左和向右滑动以更改基础表。我使用平移手势的动作方法来移动表格。工作正常。

然而,UIView&它的平移手势会干扰向上/向下滚动UITableView。如何将向上/向下滚动发送到桌面并在视图区域保持左右?

 ---------------------------------------
 |                                     |
 |             ----------------------  |
 |             |                    |  |
 |             |                    |  |
 |             |                    |  |
 | UITableView |                    |  |
 |             |        UIView      |  |
 |             |          +         |  |
 |             |       PanGesture   |  |
 |             |                    |  |
 |             |                    |  |
 |             |                    |  |
 |             |                    |  |
 |             ----------------------  |
 |                                     |
 |                                     |
 ---------------------------------------

Pan手势触发的方法就像这样

 -(void)move:(UIPanGestureRecognizer*)sender
 {
     CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
     float xTest = fabsf(translatedPoint.x);
     float yTest = fabsf(translatedPoint.y);
     if ( xTest>yTest)
     {
         // Move table view left-right.. this works
     } else
     {
         // Send up-down scrolling gesture to table view????? How to?
     }
 }

7 个答案:

答案 0 :(得分:12)

我刚刚解决了类似的问题,除了它是垂直平底锅而不是水平平底锅。我对你的用例并不是100%肯定,所以这可能不是你想要的,但它可能会引导你朝着正确的方向前进。

我对UIPanGestureRecognizer进行了细分,并实现了touchesMoved方法,并检查手势是否有更大的水平或垂直变化。下面是一个片段。该信用属于不同的stackoverflow帖子,但我目前无法找到该链接。 (提前抱歉格式不佳,第一次发帖)

-(void)touchesMoved:(NSSet*) touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
if(self.state == UIGestureRecognizerStateFailed) return;
CGPoint currentPoint = [[touches anyObject] locationInView:self.view];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view];
moveX += prevPoint.x - currentPoint.x;
moveY += prevPoint.y - currentPoint.y;
if(!drag) {
    if(abs(moveY) > abs(moveX))
        drag = YES;
    else
        self.state = UIGestureRecognizerStateFailed;
}
}

-(void)reset
{
[super reset];
drag = NO;
moveX = 0;
moveY = 0;
}

在我的父视图控制器中,我相信在这种情况下是UITableView,我也实现了以下内容。我认为在你的情况下,如果它是一个水平平移,你会想要返回no。

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if([gestureRecognizer isKindOfClass:[VerticalPanGestureRecognizer class]])
{
    return YES;
}
return NO;
}

如果有任何不清楚的地方,请告诉我。

祝你好运!

答案 1 :(得分:3)

UIGestureRecognizer有一个属性可以阻止已识别的手势将其事件转发到视图层 - 听起来好像这是适合您的选项。尝试并将其设置为有问题的手势识别器上的NO

<强> cancelsTouchesInView

一个布尔值,用于影响在识别手势时是否将触摸传递到视图。

@property(nonatomic) BOOL cancelsTouchesInView
  

讨论

     

当此属性为YES(默认值)和接收者时   识别它的手势,那个待处理的手势的触摸   没有送到视图,以前交付的接触是   通过touchesCancelled:withEvent:消息发送给了   视图。如果手势识别器无法识别其手势或是否   此属性的值为NO,视图接收到的所有触摸   多点触控序列。

适用于iOS 3.2及更高版本。

来自UIGestureRecognizer reference

答案 2 :(得分:2)

好的,答案是将平移添加到UITableView而不是UIView。我检查手势的位置是否在(现在隐藏在xib中)UIView的边界内,如下所示:

 - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
 {
     CGPoint translation = [gestureRecognizer locationInView:self.view];
     CGRect frame = self.slideTarget.frame;
     if (CGRectContainsPoint(frame, translation))
     {
         return YES;
     } else
     {
         return NO;
     }
 }

动臂。

答案 3 :(得分:1)

我知道您希望UIView中的手势根据其方向进行处理(垂直 - &gt;滚动表,水平 - &gt;滚动UIView)。我读过-did没试过这个:UISwipeGestureRecognizer有一个属性方向 - 来自docs:

The permitted direction of the swipe for this gesture recognizer.

也许这可以帮到你?

编辑:哦,好吧,我没有意识到你正在看UIPanRecognizer(那里有太多的“滑动”)......也许你可以在平移方向“足够垂直”时将手势传递到桌面上,如translationInView:报道的那样?

答案 4 :(得分:1)

在Pan手势的方法中写下这个:

- (void)pan:(UIPanGestureRecognizer *)gesture
{
    CGPoint translatedPoint = [gesture translationInView:self.tableView];

    if (ABS(translatedPoint.y) > 10.0f) {
        self.tableView.bounds = CGRectMake(0, -translatedPoint.y, 320, 460);
    }
    if (ABS(translatedPoint.x) > 10.0f) {
        // swipe left/right code...
    }
}

在这里,您可以通过更改其边界属性来模拟滚动表格视图。但是这段代码不会反弹表视图。可以通过在平移手势开始时保存跳出属性状态,然后在手势结束时指定此属性来实现此效果。

答案 5 :(得分:0)

我可以从您的要求中了解到,当您与另一个视图进行交互时需要滚动表格。 所以视图层将如下:

的UINavigationController - &gt;查看 (导航控制器将具有UITableViewController) UITableViewController(它将具有UiTableView)

最后

UIView(UINavigationController.view subview UIView)

所以如果你在UIView上进行平移(滚动),那么你想要那样,那么你的TableView将正确滚动。

所以你需要制作一个你需要的UIView类(让我们假设是CustomView)。 然后在CustomView类中实现以下方法。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];

    // If the hitView is THIS view, return the view that you want to     receive the touch instead:
    if (hitView == self) {
        return _tableView;
    }
    else if ([hitView isKindOfClass:[UIButton class]]) {
        return hitView;
    }
    return _tableView;
}

如果您的CustomView上也有按钮子视图。 然后你也可以选择它。

请原谅我的错误解释,但我刚刚找到了解决问题的方法,我想和你分享。

如果您需要更多解释,请与我们联系。我稍后会解释。

答案 6 :(得分:0)

实施名为UIGestureReconizerDelegate的{​​{1}}方法。

默认情况下返回 - gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:,实现它​​并返回false

true.

并且,不要忘记设置手势的- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return true; } 属性。

delegate

From Apple doc

// Set the delegate of the panGesture. For example self.panGestureReconizer.delegate = ... //

  

询问代表是否应允许两个手势识别器同时识别手势。

     

返回值

     

是允许gestureRecognizer和otherGestureRecognizer同时识别他们的手势。默认实现返回NO - 不能同时识别两个手势。

     

讨论

     

当gestureRecognizer或otherGestureRecognizer识别手势会阻止其他手势识别器识别其手势时,会调用此方法。请注意,保证返回YES可以同时识别;另一方面,返回NO不能保证防止同时识别,因为其他手势识别器的代表可能会返回YES。

Read more