在 UIPanGestureRecognizer 和重新启用的 UIScrollView 之间连续滚动
Posted
技术标签:
【中文标题】在 UIPanGestureRecognizer 和重新启用的 UIScrollView 之间连续滚动【英文标题】:Continuous scrolling between UIPanGestureRecognizer and re-enabled UIScrollView 【发布时间】:2012-01-03 20:17:38 【问题描述】:我有一个启用了分页的UIScrollView
,并且我已经向其中添加了我自己的UIPanGestureRegonizer
。在某些情况下,我的视图控制器将设置scrollview.scrollEnabled = NO
,然后将平移手势识别器添加到其中(我没有使用滚动视图自己的识别器)。
因此,滚动已禁用,但我正在等待来自我的手势识别器的用户触摸。当它识别出来时,它会调用我重新启用滚动的操作。
问题是,当用户的手指仍然向下时,我的滚动视图没有用手指跟踪。在抬起手指然后再次拖动之前,它不会开始滚动。所以我的手势识别器正在吞下所有的触摸,而不是将任何触摸转发到滚动视图。
我尝试切换panGestureRecognizer.cancelsTouchesInView = NO;
,但它似乎没有任何效果(我目前正在删除此识别器,一旦我重新启用滚动但我是否这样做并不能解决我的问题)。我还查看了 UIGestureRecognizer
的 delays...
属性,但它们似乎也没有帮助。
有什么想法吗?如何让这些事件继续转发到我的滚动视图?
【问题讨论】:
您是否尝试在gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
方法中返回YES
?
@Hejazi 是的,我也实现了那个委托方法(并设置了我的委托),但是当手指仍然向下时它不会被调用(只有当我抬起并再次放下手指时这个委托方法是否被调用)。
【参考方案1】:
如果您只针对 ios 5 及更高版本,答案会简单一些,因为在这种情况下,您确实应该重用 UIScrollView panGestureRecognizer 属性。
无论如何,关键步骤是不要重用scrollEnabled,而是继承UIScrollView,创建你自己的属性来管理这个状态,并覆盖setContentOffset:。
- (void) setContentOffset:(CGPoint)contentOffset
if(self.programaticScrollEnabled)
[super setContentOffset:contentOffset];
这是一种可能的 iOS 4+ 解决方案:
-
子类 UIScrollView(或子类 UIScrollView 的另一个子类,具体取决于您的需要)。
覆盖所有初始化程序以确保调用您的设置代码。
声明 BOOL 属性并覆盖 setContentOffset: 如上所述。
在您的设置代码中,设置 UIPanGestureRecognizer 并设置您的状态变量以允许程序化滚动(假设这是您想要的默认状态):
panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)] autorelease];
//These properties may change according to your needs
panRecognizer.cancelsTouchesInView = NO;
panRecognizer.delaysTouchesBegan = NO;
panRecognizer.delaysTouchesEnded = NO;
[self addGestureRecognizer:panRecognizer];
panRecognizer.delegate = self;
self.programaticScrollEnabled = YES;
管理哪些手势可以同时发生。就我而言:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
return YES;
在您需要的任何地方重新启用程序化滚动。例如:
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
self.programaticScrollEnabled = YES;
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
self.programaticScrollEnabled = YES;
return YES;
【讨论】:
以上是关于在 UIPanGestureRecognizer 和重新启用的 UIScrollView 之间连续滚动的主要内容,如果未能解决你的问题,请参考以下文章
在 UILongPressGestureRecognizer 上启用 UIPanGestureRecognizer
UIPanGestureRecognizer 在视图中使用 UIScrollView
在播放 UIAnimation 时执行 UIPanGestureRecognizer