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

Posted

技术标签:

【中文标题】将垂直滚动手势传递给下面的 UITableView【英文标题】:Passing vertical scrolling gesture to UITableView below 【发布时间】:2012-10-18 17:35:06 【问题描述】:

(为清楚起见进行了编辑)

我有一个 UITableView。最重要的是一个带有平移手势的 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?
     
 

【问题讨论】:

【参考方案1】:

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

我将 UIPanGestureRecognizer 子类化,并实现 touchesMoved 方法,并检查手势是否有较大的水平或垂直变化。下面是一个sn-p。信用属于不同的***帖子,但我目前找不到链接。 (第一次发帖,格式不好先见谅)

-(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;

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

祝你好运!

【讨论】:

在我的例子中,父视图是一个 UIViewController。我尝试了上面的代码,但仍然没有将滚动传递到表格。【参考方案2】:

UIGestureRecognizer 有一个属性,可以防止识别的手势将其事件转发到视图层次结构 - 听起来好像这对您来说是正确的选择。尝试一下,并将其设置为您有问题的手势识别器上的NO

cancelsTouchesInView

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

@property(nonatomic) BOOL cancelsTouchesInView

讨论

当此属性为 YES(默认)且接收者 识别其手势,该手势的未决触摸 未传递到视图,之前传递的触摸是 通过 touchesCancelled:withEvent: 消息取消发送到 看法。如果手势识别器无法识别其手势,或者如果 此属性的值为 NO,视图接收所有触摸 多点触控序列。

适用于 ios 3.2 及更高版本。

来自UIGestureRecognizer reference。

【讨论】:

这个好像没有效果。【参考方案3】:

好的,答案是将平移添加到 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;
     
 

轰隆隆。

【讨论】:

【参考方案4】:

我了解您希望根据其方向(垂直 -> 滚动表,水平 -> 滚动 UIView)处理 UIView 中的手势。我读过 - 没有尝试过 - 关于这个: UISwipeGestureRecognizer 有一个属性方向 - 来自文档:

The permitted direction of the swipe for this gesture recognizer.

也许这对你有帮助?

编辑:哦,好吧,我没认出你在看 UIPanRecognizer(那里“滑动”太多)......当平移方向“足够垂直”时,也许你可以将手势传递给桌子,正如translationInView:..?所报告的那样?

【讨论】:

【参考方案5】:

在你的 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...
    

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

【讨论】:

【参考方案6】:

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

UINavigationController-->视图 (导航控制器会有 UITableViewController) UITableViewController(会有UiTableView)

最后

UIView(UINavigationController.view 子视图 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 也有按钮子视图。 然后你也会得到它的选择。

请原谅我的错误解释,但我刚刚为我的问题找到了这个解决方案,我想与你分享。

如果您需要更多解释,请告诉我。我稍后会解释。

【讨论】:

此代码实际上会将您的控件发送到 TableView,您无需使用 UIPanGesture 来执行表格滚动。【参考方案7】:

实现UIGestureReconizerDelegate 方法,命名为 - gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:

默认返回false,实现后返回true.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

    return true;

而且,别忘了设置手势的delegate 属性。

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

From Apple doc

(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

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

返回值

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

讨论

当通过gestureRecognizer 或otherGestureRecognizer 识别手势会阻止其他手势识别器识别其手势时调用此方法。注意返回YES保证允许同时识别;另一方面,返回 NO 并不能保证防止同时识别,因为其他手势识别器的委托可能会返回 YES。


Read more

【讨论】:

以上是关于将垂直滚动手势传递给下面的 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

具有共享滚动手势的嵌套 UITableView

手势识别器和 TableView

如何拦截垂直滑动手势

UITableView 和 UIGestureRecogniser

将删除滑动手势从 UIPageViewController 传递给 UITableView

滑动垂直手势无法使用UITableView