iOS 关于UIScrollView嵌套关联滑动的解决思路

作为iOS开发者,我们的苹果爸爸建议最好不要嵌套UIScrollView。然而,设计师大大并不会关心我们的苹果爸爸~
关于UIScrolView的嵌套问题,网上也有很多的解决办法,所以在阅读一些解决方案之后,有了一些自己的想法。

个人思路

主要用scrollView的偏移量contentOffset以及自带pan手势的滑动速度velocityInView:使scrollView做关联

注意

本文只是提供一种思路,因此仅用一个superScrollView嵌套一个childScrollView做示例,由本人从多标签生成的相应个数的scrollViews中提取。若有不足,感谢大家给予补充指正。

最终效果
2018-05-04 17_10_04.gif

界面搭建

首先,新建继承自UIScrollViewBaseScrollView,遵循协议UIGestureRecognizerDelegate并打开scrollView的多手势识别

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

创建对象 BaseScrollView *superScrollViewUIScrollView *childScrollView,并设置代理

iOS 关于UIScrollView嵌套关联滑动的解决思路_第1张图片
image.png

即: headerViewchildScrollView组成了superScrollViewcontentSize

此时的效果类似


2018-05-04 17_07_33.gif

显然,这并不是我们想要的效果。

添加关联判断

接下来需要我们在- (void)scrollViewDidScroll:(UIScrollView *)代理方法中设置一些细节

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    UIScrollView *childScrollView = self.childScrollView;
    UIScrollView *superScrollView = self.superScrollView;

    ///临界值
    CGFloat topHeight = self.headerView.bounds.size.height;
    ///scrollView 滑动偏移量
    CGFloat offsetY_super = superScrollView.contentOffset.y;
    CGFloat offsetY_sub   = childScrollView.contentOffset.y;
    
    ///pan手势 速度 ======> 判断滑动方向(下滑 -- y为正)
    CGPoint velocity_sub    = [childScrollView.panGestureRecognizer velocityInView:childScrollView];
    CGPoint velocity_super  = [superScrollView.panGestureRecognizer velocityInView:scrollView];
    
    
    ///滑动的手指放开时,速度变为 0
    if (offsetY_sub > 0 && velocity_sub.y == 0 && velocity_super.y == 0) {
        superScrollView.contentOffset = CGPointMake(0, topHeight);
    }
    
    ///当速度为 0 时,不做以下代码处理
    if (velocity_sub.y == 0 || velocity_super.y == 0) {
        return;
    }
    
    ///以下处理速度不为零的情况
    
    if (offsetY_super >= 0 && offsetY_super < topHeight && velocity_sub.y < 0) {
        // (a)手指上滑时,若superScrollView未超过临界值,则设置childScrollView的contentOffset
        childScrollView.contentOffset = CGPointZero;
    }

    if (offsetY_sub > 0 && velocity_sub.y > 0) {
        // (b)手指下滑时,若childScrollView未到顶点,则设置superScrollView的contentOffset
        superScrollView.contentOffset = CGPointMake(0, topHeight);
    }
    else if (velocity_super.y > 0) {
        // (c) 若childScrollView到顶点,固定childScrollView的contentOffset
        childScrollView.contentOffset = CGPointZero;
    }
    
}

以上,若有补充指正,感谢评论分享

你可能感兴趣的:(iOS 关于UIScrollView嵌套关联滑动的解决思路)