是否可以自定义触发UIScrollView滚动的滑动手势识别?

时间:2013-04-25 09:02:59

标签: ios objective-c cocoa-touch uiscrollview

我已经从UIScrollView创建了一个自定义子类,并实现了touchesBegantouchesMovedtouchesEndedtouchesCancelled方法。

然而,我对事情的运作方式并不满意。特别是,当被提及的方法被调用时,UIScrollView何时决定实际滚动(拖动)。

即使第一触摸点和最后一个触摸点之间的差异在垂直方向上非常小,

UIScrollView也会滚动。所以我可以几乎水平滑动,UIScrollView将根据这个小差异向上或向下滚动。(在正常使用情况下这是完全正常的)

Default UIScrollView behavior

这两次滑动都会导致UIScrollView向下滚动。

但是我感兴趣的是可以以某种方式调整它,所以它的行为如下:

Desired behavior

基本上,touchesBegan和相关方法会接近水平滑动并且不会启动滚动。然而,绿色滑动方向仍会启动滚动...

编辑:

我忘了提及,touchesBegan如果你在屏幕上短时间握住手指然后移动它,亲戚就会被召唤。所以不是经典的滑动手势......

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

克里斯托弗·纳萨尔正确地指出我应该使用UIPanGestureRecognizer,所以我尝试了一下。

我发现如果您将UIPanGestureRecognizer添加到包含UIScrollView superview 。然后UIScrollView内置平移手势识别器将以您想要的确切方式与您自己的UIPanGestureRecognizer配对!

水平和近水平滑动将由 superview UIPanGestureRecognizer和所有其他垂直滑动通过平移手势内置的UIScrollView(自定义)拾取识别器并使其滚动...

我认为UIScrollView是按照这种方式设计的,因为默认行为是只有其中一个平移手势识别器触发,或者如果UIScrollViewUIPanGestureRecognizerDelegate返回YES,则两者同时触发方法:

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

然而,似乎UIScrollView具有额外的逻辑来选择性地禁用(对于水平滑动)其自己的声明识别器,以防另一个存在。

也许有人在这里了解更多细节。

总而言之,我的解决方案是在UIPanGestureRecognizer内的viewDidLoad内添加UIViewController。(注意:UIScrollView作为添加子视图UIViewController视图)

UIPanGestureRecognizer *myPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.view addGestureRecognizer:myPanGestureRecognizer];

然后添加处理程序方法:

- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
    NSLog(@"Swiped horizontally...");
}