将垂直滚动手势传递给下面的 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 和 UIGestureRecogniser