使用双指平移和缩放分页UIScrollView

时间:2011-11-06 03:43:23

标签: ios uiscrollview zoom multi-touch panning

可轻松复制测试用例:下载Apple的PhotoScroller示例应用程序,并尝试对其进行调整,以便平移(在缩放的图像周围和每个图像之间)仅适用于两个手指。

panGestureRecognizerpagingScrollView的{​​{1}}设置为仅接受最小值&最多2次触摸似乎是一个很好的起点,但它不起作用。它允许你用两根手指滚动图像就好*,但分页然后不起作用。

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

* 编辑:实际上,在这种情况下它不能正常滚动。只需轻轻一按,视图就不再平滑......

更新:我还在努力解决这个问题。非常感谢来自使用imageScrollViewUIGestureRecognizer s的人的一些意见。

修改

UIScrollView类设置为仅接受两次触摸:

ImageScrollView

- (id)initWithFrame:(CGRect)frame { // ... // Template code // ... [self.panGestureRecognizer setMinimumNumberOfTouches:2]; [self.panGestureRecognizer setMaximumNumberOfTouches:2]; } 的{​​{1}}设置为仅接受两次触摸:

PhotoViewController

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

3 个答案:

答案 0 :(得分:1)

<强> 问题

UIPanGestureRecognizer UIScrollView 的基础(不幸的是,这也会影响UIPageViewController maximumNumberOfTouches 的行为不符合预期 - minimumNumberOfTouches 但总是正确限制下端。

在监控这些参数时,他们似乎完成了自己的工作 - 只是UIScrollView不尊重他们而忽略了他们的价值观!

<强> REMEDY

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

UIScrollView scrolling only with one finger

<强> 顺便说一句:

您在 one 手指与 two 手指平移之间遇到的差异是因为您只用一根手指就可以使用 panGestureRecognizer 即可。使用两根手指 pinchGestureRecognizer (也可以同时平移)启动并且您没有减速阶段,视图会立即停止平移和缩放释放你的手指。停用pinchGestureRecognizer,您会看到panGestureRecognizer接管 - 即使是两根手指 - 并且平移再次顺利...... ;-)

同时 - etvoilà...

委托回调以获得完美的同时双指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接管(默认),而是平稳地进入下一个平移/减速阶段 - 就像用一根手指一样!

FOR PERFECTIONISTS:

将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;
}

快乐的手势识别!

答案 1 :(得分:0)

子类似乎是这个

的方法

文档说明您可以通过子类化来处理滚动手势的处理方式。

UIScrollView Class Reference

具体地

  

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

您还应该查看此SO帖子Scrolling with two fingers with a UIScrollView

答案 2 :(得分:0)

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