我通过以下方式解决了这个问题。我对它不太满意,因为它在我看来太复杂了,但它可以工作(请注意,下面的代码是我的代码的简化、未经测试的版本,这是由于不同的 UI 更复杂):
我有 3 个控制滚动的属性:
@property (nonatomic, assign) CGFloat currentPanY;
@property (nonatomic, assign) BOOL scrollA;
@property (nonatomic, assign) BOOL scrollB;
两步滚动:
禁用 B 的滚动,启用 A 的滚动。
这允许滚动 A 。
当 A 到达其最大位置时,禁用 A 的滚动,启用 B 的滚动:
-(void)scrollViewDidScroll: (UIScrollView *)scrollView {
if (scrollView.contentOffset.y >= self.maxScrollUpOffset) {
[scrollView setContentOffset:CGPointMake(0, self.maxScrollUpOffset) animated:NO];
self.scrollviewA.scrollEnabled = NO;
self.scrollviewB.scrollEnabled = YES;
self.scrollB = YES;
}
}
这会产生以下效果:
当 A 向上滚动时,它会在达到其最大尺寸时停止滚动。但是 B 不会开始滚动,因为 A 的平移手势识别器不会将其动作转发给 B 的平移手势识别器。因此必须抬起手指并开始第二次滚动。然后,B 将滚动。这给出了两步滚动。
连续滚动:
对于连续滚动,B 必须滚动,同时开始滚动 A 的手指继续向上移动。为了检测这一点,我在 A 中添加了一个进一步的平移手势识别器,并使其能够与 A 和 B 的内置手势识别器同时检测手势:
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer {
return YES;
}
在这个额外的平移手势识别器的动作中,我计算了在达到 A 的滚动限制后手指向上移动的距离。通过这个距离,B 然后以编程方式滚动:
- (void)panGestureRecognizerAction:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state != UIGestureRecognizerStateChanged) {
self.currentPanY = 0;
self.scrollB = NO;
self.scrollA = NO;
} else {
CGPoint currentTranslation = [recognizer translationInView:self.scrollviewA];
CGFloat currentYup = currentTranslation.y;
if (self.scrollA || self.scrollB) {
if (self.currentPanY == 0) {
self.currentPanY = currentYup;
}
CGFloat additionalYup = self.currentPanY - currentYup;
if (self.scrollA) {
CGFloat offset = self.scrollviewA.scrollUpOffset + additionalYup;
if (offset >= 0) {
self.scrollviewA.contentOffset = CGPointMake(0, offset);
} else {
self.scrollviewA.contentOffset = CGPointZero;
}
} else if (self.scrollB){
self.scrollviewB.contentOffset = CGPointMake(0, additionalYup);
}
}
}
}
还有一个缺点:
如果您开始滚动,抬起手指,然后让 scrollView 减速,它的行为类似于 2 阶段滚动,因为附加的平移手势识别器不会识别任何平移手势。