2011-11-06 77 views
5

测试用例是很容易复制:下载苹果的PhotoScroller示例应用程序,并尝试去适应它,这样平移(包括周围缩放图像,以及之间的每个图像)只能用两个手指。分页的UIScrollView用两个手指平移和缩放

设置panGestureRecognizer同时为pagingScrollViewimageScrollView只接受一个最小&最大的2个触摸似乎是一个良好的开端,但它不工作。它可以让你用两根手指在图像上滚动*,但是分页不起作用。

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

* 编辑:其实,它在这种情况下不会正常滚动。视图不再像单触一样顺畅地滑动...

更新:我仍然在为这一个而努力。我希望从谁已与UIGestureRecognizer S和UIScrollView在扮演各地的人一些输入。

编辑

设置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]; 
} 

这些修改是直接在PhotoS上面制作的croller示例应用程序。我希望这些简单的改变为两个手指交互工作,但是副作用都是奇数(如上所述)。

+0

正在下载。 108mb o_O – 0xSina

+0

@PragmaOnce:是的,很抱歉链接这么大的样本。它包含分页滚动视图的所有全尺寸和平铺图像。漂亮的图片没有必要证明我的观点,但嘿...! – Stuart

+1

UIScrollView有它自己的私人手势识别器。即使是暴露的panGestureRecognizer是一个私人类。 'NSLog(@“%@”,[pagingScrollView valueForKeyPath:@“gestureRecognizers.class”]);' - >'(UIScrollViewDelayedTouchesBeganGestureRecognizer,UIScrollViewPanGestureRecognizer,UIScrollViewPagingSwipeGestureRecognizer)''。我认为你需要选择一个不同的用户界面。 –

回答

0

这样看来,这是根本无法支持,或非常非常困难的(即滚动从头开始自己的滚动视图)。我使用了Apple技术支持事件,他们无法提供帮助。如果解决方案变得可用,我会很高兴地将其标记为接受的答案!

+0

完全不可能 - 易于修复... - ;-)查看我的详细解答... – mramosch

0

子类似乎是去与此

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

UIScrollView Class Reference

具体地说

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

你也应该看看这个帖子SO,Scrolling with two fingers with a UIScrollView

+0

感谢您的回复,我很感激。然而 - 暂时关键 - 这是一个更具体问题的非常通用的答案。 'ImageScrollView'已经被子类化了,我也尝试过使用分页滚动视图的子类化,但是没有用。我之前看到过链接的SO帖子,尽管过去它对我有用,但答案实际上都是过时的(即使是通过滚动视图的手势识别器迭代的答案 - 在iOS 5中也可以更容易地实现使用我的问题中的代码)。 – Stuart

+0

我希望你能明白我想给出一个答案,提供更详细的洞察,以了解如何定制一个子类以实现所需的行为。例如,因为'touchesShouldBegin ...'&'touchesShouldCancel ...'只在每个触摸序列开始时被调用一次,所以如何处理'ImageScrollView'应该平移(放大时)的情况,然后当滚动到达图像的边缘时,分页滚动视图应该接管? – Stuart

+0

我可以充分意识到,我希望你能得到更有帮助的答案。我会看看我是否可以研究一些。我已经使用scrollviews手势识别器,但不是这种情况。 –

0

问题

UIPanGestureRecognizer被下方的UIScrollView(其遗憾的是也影响UIPageViewController)的maximumNumberOfTouches不表现为预期 - 的minimumNumberOfTouches然而,总是有限的它的下端正确。

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


补救措施

你可以在我的答案的解决方案:

UIScrollView scrolling only with one finger


BTW:

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


方法同步 - 瞧等...

一个完美的同时手指2和 scrolling行为 zooming代表

回调:

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

快乐手势识别!