繁体   English   中英

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

[英]Paging UIScrollView with two-finger pan and zoom

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

设置panGestureRecognizer同时为pagingScrollViewimageScrollView只接受2台触摸一个最大和最小似乎是一个良好的开端,但它不工作。 它允许你用两根手指滚动图像就好*,但是分页然后不起作用。

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

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

更新:我还在努力解决这个问题。 我很感激来自使用过UIGestureRecognizerUIScrollView的人的一些意见。

编辑

ImageScrollView类设置为仅接受两个触摸:

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

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

PhotoViewControllerpagingScrollView设置为仅接受两个触摸:

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

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

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

问题

UIPanGestureRecognizerUIScrollView (不幸的是它也影响UIPageViewController )的基础时, maximumNumberOfTouches的行为不符合预期 - minimumNumberOfTouches总是正确地限制下端。

当监视这些参数时,它们似乎完成了它们的工作 - 只是UIScrollView不尊重它们并忽略它们的值!


补救措施

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

UIScrollView只用一根手指滚动


BTW:

您在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接管(默认),而是平稳地进入下一个平移/减速阶段 - 就像用一根手指!


对于完美主义者:

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

快乐的姿态识别!


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

子类似乎是这样的方式

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

UIScrollView类参考

特别

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM