拦截 UIScrollView 滚动

Posted

技术标签:

【中文标题】拦截 UIScrollView 滚动【英文标题】:Intercepting UIScrollView Scrolls 【发布时间】:2013-06-20 10:55:44 【问题描述】:

我在 UIScrollView 中有一个 UIScrollView 和一个 UITableView。

我想拦截 UITableView 的滚动,并且仅在超级视图 (UIScrollView) 达到特定 contentOffset 时才允许滚动。

我已经创建了 UIScrollView 和 UITableView 的子类,我如何在用户仍在滚动时捕获滚动事件并拦截滚动

我想要完成的示例: UITableView 将有一个标题,如果我向下滚动标题将折叠到原始大小的 30% 并在顶部保持可见。在我滚动回 UITableView 的顶部后,我希望标题展开。换句话说,我想使用可以折叠/展开的标题来扩展 UITableView 的滚动。

可能有更好的方法来实现这一点,我愿意接受建议。

【问题讨论】:

如何使用滚动视图委托方法scrollViewDidScroll:? 【参考方案1】:

可能有更好的方法,但这个解决方案对我有用。

UITableView(我们称它为 innerScrollView)在 UIScrollView(我们称它为 scrollView)内无论主视图是什么(我们称它为 view)。 在您的视图控制器中为 innerScrollView (self.innerScrollView) 设置一个出口。 在 XIB 或代码中设置退回:scrollView.bounces = YESinnerScrollView.bounces = NO。 最初将 innerScrollView 的滚动设置为禁用。 在代码 (viewDidLoad:) 中将scrollView.contentSize.height 设置为view.frame.size.height + 70% 的标题要消失。调整 innerScrollView 的大小以将调整后的 contentView 填充到底部。

将您的视图控制器设置为 scrollView 的委托并实现scrollViewDidScroll:,如下所示:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
   CGFloat maxYOffset = self.scrollView.contentSize.height - self.scrollView.frame.size.height;
   CGFloat minInnerYOffset = self.innerScrollView.contentInset.top;
   CGFloat currentYOffset = scrollView.contentOffset.y;
   CGFloat newYOffsetDelta = currentYOffset - maxYOffset;
   CGFloat currentInnerYOffset = self.innerScrollView.contentOffset.y;

   if (scrollView.contentOffset.y >= maxYOffset) 
       self.innerScrollView.scrollEnabled = YES;
       self.scrollView.contentOffset = CGPointMake(0, maxYOffset);

       if (currentYOffset != maxYOffset) 
           self.innerScrollView.contentOffset = CGPointMake(0, currentInnerYOffset + newYOffsetDelta);
       
   
   else if (currentInnerYOffset > minInnerYOffset) 
       self.scrollView.contentOffset = CGPointMake(0, maxYOffset);
       self.innerScrollView.contentOffset = CGPointMake(0, currentInnerYOffset + newYOffsetDelta);
   
   else if (currentYOffset < scrollView.contentInset.top) 
       scrollView.contentOffset = CGPointMake(0, scrollView.contentInset.top);
   
   else 
       self.lowerScrollView.scrollEnabled = NO;
   

我刚刚整理好并快速测试了它。这一切似乎都有效,但可能需要一些改进和调整。无论如何,这至少应该让你开始。

【讨论】:

【参考方案2】:

嗯,你应该使用下面的 UIScrollViewDelegate 方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
   // here perform the action you need

【讨论】:

问题是当该方法被调用时视图已经被滚动,我如何禁用仅向一个方向滚动并使用该方法将其发送到超级视图?

以上是关于拦截 UIScrollView 滚动的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 UITouch 与 UIScroll

拦截 UIScrollView 滚动

UIScrollView 不使用 RubyMotion 滚动

滚动 UIScrollView 时如何缩放

UIScrollView 滚动问题之上的 UICollectionView

UICollectionViewCell与UIScrollView取消didSelectItemAtIndexPath