13

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

我有一个 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?
     }
 }
4

7 回答 7

11

我刚刚解决了一个类似的问题,除了它是针对垂直平底锅而不是水平平底锅。我不能 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;
}

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

祝你好运!

于 2012-10-18T20:45:20.387 回答
3

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

cancelsTouchesInView

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

@property(nonatomic) BOOL cancelsTouchesInView

讨论

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

在 iOS 3.2 及更高版本中可用。

来自UIGestureRecognizer 参考

于 2012-10-18T18:03:07.510 回答
2

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

繁荣。

于 2012-10-19T12:02:53.720 回答
1

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

The permitted direction of the swipe for this gesture recognizer.

也许这可以帮助你?

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

于 2012-10-18T19:54:17.587 回答
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...
    }
}

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

于 2012-10-18T21:00:53.333 回答
0

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

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

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

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

于 2016-04-02T10:50:09.453 回答
0

实现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 = ... //

来自苹果文档

(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

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

返回值

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

讨论

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


阅读更多

于 2016-06-23T09:38:15.400 回答