8

测试用例很容易复制:下载 Apple 的PhotoScroller示例应用程序,并尝试对其进行调整,以便仅用两根手指进行平移(围绕缩放的图像,以及在每个图像之间)。

panGestureRecognizerthepagingScrollView和 the设置imageScrollView为仅接受最少和最多 2 次触摸似乎是一个不错的起点,但它不起作用。它可以让您用两根手指滚动图像*,但是分页不起作用。

我已经尝试了很多设置和自定义手势识别器的组合,我有点难过。自定义滚动视图子类是否有用,或者我可以以某种方式操纵滚动视图委托方法以使其工作?

*编辑:实际上,在这种情况下它不能很好地滚动。视图不再像单次触摸那样平滑滑动...

更新:我仍在努力解决这个问题。我会很感激那些玩过UIGestureRecognizers 和UIScrollViews 的人的一些意见。

编辑

ImageScrollView类设置为只接受两次触摸:

- (id)initWithFrame:(CGRect)frame
{
    // ...
    // Template code
    // ...

    [self.panGestureRecognizer setMinimumNumberOfTouches:2];
    [self.panGestureRecognizer setMaximumNumberOfTouches:2];
}

设置PhotoViewController'spagingScrollView只接受两次触摸:

- (void)loadView
{
    // ...
    // Template code
    // ...

    [pagingScrollView.panGestureRecognizer setMinimumNumberOfTouches:2];
    [pagingScrollView.panGestureRecognizer setMaximumNumberOfTouches:2];
}

这些修改直接在 PhotoScroller 示例应用程序之上进行。我希望这些简单的更改适用于两指交互,但是副作用很奇怪(如上所述)。

4

3 回答 3

1

这似乎是不可能的,或者非常非常困难(即从头开始滚动您自己的滚动视图)。我使用了 Apple 技术支持事件,但他们无法提供帮助。如果有可用的解决方案,我会很乐意将其标记为已接受的答案!

于 2013-01-11T15:50:58.820 回答
1

问题

当 a 的UIPanGestureRecognizer基础是 a UIScrollView(不幸的是,这也会影响UIPageViewController)时,maximumNumberOfTouches它的行为并不像预期的那样 -minimumNumberOfTouches但是总是正确地限制下端。

当监控这些参数时,他们似乎在做他们的工作——只是UIScrollView不尊重他们并忽略了他们的价值观!


补救措施

您可以在我的回答中找到解决方案:

UIScrollView 只能用一根手指滚动


顺便提一句:

one您在手指平移和手指平移之间体验到的区别two是因为您用一根手指使用panGestureRecognizer. 用两根手指pinchGestureRecognizer(也可以同时平移)启动,您没有减速阶段,松开手指后视图立即停止平移和缩放。停用pinchGestureRecognizer,您会看到panGestureRecognizer接管 - 即使是两个手指 - 并且平移再次平滑...... ;-)


同时 - 等等...

为完美的同时 2 根手指scrollingzooming行为委托回调:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = NO;
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = NO;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    self.pinchGestureRecognizer.enabled = YES;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = YES;
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {    
    self.panGestureRecognizer.enabled = NO;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {    
    self.panGestureRecognizer.enabled = YES;
}

Fast pinch开始放大!
Fast pan开始平移!

用两个新手指在屏幕上停止减速平移并再次开始拖动不会让笨拙的 pinchGestureRecognizer 接管(默认),而是平稳地进入下一个平移/减速阶段 - 就像用一根手指!


对于完美主义者:

将 2 根手指放在屏幕上,然后 -现在不要移动- 如果您在前 0.5 秒内未开始捏合,则会zooming被锁定并且只有panning以下可用:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

    if ([gestureRecognizer.view isMemberOfClass:[MY_CustomScrollView class]]) {

        NSLog(@"IN SCROLL-VIEW...");
        if (gestureRecognizer == self.pinchGestureRecognizer) {
            if (_pinchGestureLocked) {
                NSLog(@"...but TOO late for zooming...");
                return NO;
            } else {
                NSLog(@"...ZOOMING + PANNING...");
                return YES;
            }
        } else if (gestureRecognizer == self.panGestureRecognizer){
            if (gestureRecognizer.numberOfTouches > 2) {
                NSLog(@"...but TOO many touches for PANNING ONLY...");
                return NO;
            } else {
                NSLog(@"...PANNING...");
                return YES;
            }
        } else {

            NSLog(@"...NO PAN or PINCH...");
            return YES;
        }

    } else {
        NSLog(@"NOT IN SCROLL-VIEW...");
    }

    return YES;

}  

BOOL _pinchGestureLocked = NO;

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    _pinchGestureLocked = YES;
}

- (void) touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    _pinchGestureLocked = NO;
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    _pinchGestureLocked = NO;
}

快乐的手势识别!


于 2016-10-16T17:09:50.890 回答
0

子类化似乎是解决这个问题的方法

该文档指出,您可以通过子类化来操纵滚动手势的处理方式。

UIScrollView 类参考

具体来说

子类可以覆盖 touchesShouldBegin:withEvent:inContentView:、pagingEnabled 和 touchesShouldCancelInContentView: 方法(由滚动视图调用)来影响滚动视图处理滚动手势的方式。

您还应该看看这篇 SO 帖子,使用 UIScrollView 用两根手指滚动

于 2011-11-15T18:38:19.563 回答