是否可以自定义触发 UIScrollView 滚动的滑动手势识别?
Posted
技术标签:
【中文标题】是否可以自定义触发 UIScrollView 滚动的滑动手势识别?【英文标题】:Is it possible to customize swiping gesture recognition that triggers UIScrollView scroll? 【发布时间】:2013-04-25 09:02:59 【问题描述】:我从UIScrollView
创建了一个自定义子类,并实现了touchesBegan
、touchesMoved
、touchesEnded
和touchesCancelled
方法。
但是,我对事情的运作方式并不满意。特别是,提到的方法何时被调用,UIScrollView
何时决定实际滚动(拖动)。
UIScrollView
滚动,即使第一个触摸点和最后一个触摸点在垂直方向上的差异很小。所以我几乎可以水平滑动,UIScrollView
会根据那个微小的差异向上或向下滚动。(这在正常用例中非常好)
这两种滑动都会导致UIScrollView
向下滚动。
但是我很感兴趣,是否可以以某种方式对其进行调整,使其行为如下:
基本上,几乎水平的滑动会被touchesBegan
和相关方法拾取,并且不会启动滚动。然而,绿色的滑动方向仍会启动滚动...
编辑:
我忘了提,touchesBegan
和亲戚如果您在屏幕上按住手指一小段时间然后移动它,就会被呼叫。所以不是经典的滑动手势......
【问题讨论】:
【参考方案1】:Ivan,我认为您正在尝试做与 Facebook 页面相同的效果,并拖动您的滚动视图,因此让滚动视图跟随您的手指,如果正确,我建议您忘记触摸事件,并从UIPanGesture ,在这些情况下它是最好的,所以在调用该手势的委托中,为其添加以下代码:
//The sender view, in your case the scollview
UIScrollView* scr = (UIScrollView*)sender.view;
//Disable the scrolling flag for the sake of user experience
[scr setScrollEnabled:false];
//Get the current translation point of the scrollview in respect to the main view
CGPoint translation = [sender translationInView:self.view];
//Set the view center to the new translation point
float translationPoint = scr.center.x + translation.x;
scr.center = CGPointMake(translationPoint,scr.center.y);
[sender setTranslation:CGPointMake(0, 0) inView:self.view];
【讨论】:
好点!我刚刚尝试了 Facebook 应用程序,似乎就是这样......如果你向左或向右滑动,新闻提要(可能是 UIScrollView)会滑到一边......我现在要试试你的建议。但是我必须注意,我实际上并没有尝试打开侧边菜单,而是实际上改变了 NSInteger 变量(增加/减少)关于水平滑动或拖动的值......【参考方案2】:Christopher Nassar 正确地指出我应该使用UIPanGestureRecognizer
,因此我对其进行了一些试验。
我发现如果您将UIPanGestureRecognizer
添加到包含您的UIScrollView
的superview。然后UIScrollView
内置平移手势识别器将与您自己的UIPanGestureRecognizer
以我想要的确切方式一起工作!
水平和接近水平的滑动将被 superview 的 UIPanGestureRecognizer
拾取,而所有其他垂直滑动将被内置的平移手势识别器 UIScrollView
(自定义)拾取并导致它滚动...
我想UIScrollView
是这样设计的,因为默认行为是只有这些平移手势识别器中的一个触发,或者如果UIScrollView
从这个UIPanGestureRecognizerDelegate
方法返回YES,则同时触发:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
但是,UIScrollView
似乎有额外的逻辑来选择性地禁用(对于水平滑动)它自己的平移识别器,以防另一个存在。
也许这里有人知道更多细节。
所以总结一下,我的解决方案是在我的UIViewController
中的viewDidLoad
中添加一个UIPanGestureRecognizer
。(注意:UIScrollView
作为一个 subview 添加到那个@ 987654337@查看)
UIPanGestureRecognizer *myPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.view addGestureRecognizer:myPanGestureRecognizer];
然后添加处理方法:
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
NSLog(@"Swiped horizontally...");
【讨论】:
以上是关于是否可以自定义触发 UIScrollView 滚动的滑动手势识别?的主要内容,如果未能解决你的问题,请参考以下文章
自定义 UIView 中的 UIScrollView 不滚动
当我无法使用 UIScrollView 时,如何在自定义 UIView 中模拟惯性滚动?