美文网首页代码片段别人的iOS精华iOS技术专题
UIScrollView嵌套UIScrollView的滚动处理

UIScrollView嵌套UIScrollView的滚动处理

作者: Everdinner | 来源:发表于2016-07-31 16:42 被阅读4161次

先来整体效果图给以说明

  页面整体结构是一个大的滚动视图嵌套了三个可以滚动的子视图,起初在做这种效果时,搜了一下网上并没有找到合适的解决方案,于是在自己动手实现后拿出来分享一下,如果你在开发中也遇到了产品提的这种奇葩需求,相信这会是一个不错的解决方案,希望对大家有帮助!(由于是示例,效果就差那么几丢丢了~)

首先我们分析一下这个效果的几种实现方案:

1、UITableView+UIScrollView(嵌套三个子视图)

2、UIScrollView+UIScrollView(嵌套三个子视图)

这两种方案都是基于UIScrollView来实现的,不同点就在于搭建视图逻辑有所不同,在本文中我采用的是第二种方案来实现的这种效果,第一种在最终处理上是一样的。下面我们就逐步剖析一下整个实现过程

第一步:

创建一个父视图的scrollView和子视图scrollView,搭建出基础界面效果(这个相信大家都能轻松做到)

在搭建完界面后你会发现滚动下面的区域父视图并不会随着滚动的,就像这样

在滚动父视图时我们会看到如果拖拽超过了父视图的frame,底部会出现白色,而且滚动列表、图片、详情这些子视图父视图也并不会随之滚动,我们需要做的就是在这些视图滚动的时候监听滚动位置并做处理

第二步:

设置需要处理的scrollView代理,监听滚动位置,整个处理代码就在scrollViewDidScroll这个代理方法中完成,我们需要整个视图在滚动到tab的时候就停留,只能继续滚动子视图,因此我们只需判断在父视图滚动位置不超过tab头部时就随着子视图滚动而滚动,子视图在滚动中需要始终设置

```

[scrollView setContentOffset:CGPointZero];

(注意这里如果添加animated:YES是不可以的)。

```

在我们滚动父视图时就只需要判断如果滚动位置超过了tab就设置为tab的位置即可:

```

if (self.journeyScrollView.contentOffset.y >= self.titleView.y) {

[self.journeyScrollView setContentOffset:CGPointMake(0, self.titleView.y)];

}

```

为了解决子视图滚动到顶部继续拖拽导致的父视图移位不会自动返回问题,我们需要在scrollViewDidEndDragging这个代理方法中判断处理父视图的位置

```if (self.journeyScrollView.contentOffset.y < 0) {

[self.journeyScrollView setContentOffset:CGPointZero

animated:YES];

}

```

到此一个嵌套滚动的视图逻辑处理就完成了,如果你还有疑惑,可以查看本篇文章的一个示例Demo:https://github.com/lvXiaoPeng/LYEmbedScrollView

最后,如果你有更好的实现原理和解决方案,希望能告诉我,共同学习!

相关文章

网友评论

  • Lazyloading:楼主请问我用代码复写了你的效果但是在判断滑动里边判断是否是子视图时候 我的一次滑动会出现 是和否两种情况 然后导致点击在子视图上划不动的情况 但是我命名是点击在子视图滑动的你碰到过这种情况吗
    Everdinner:@Stronger_ 这个demo仅仅是一种思路的指引,真正用到项目里要优化的地方还不少,不过你说的这种情况我没有遇到过,如果想要完美的拖动处理,推荐看看评论区的一篇给scrollView添加拖动手势处理视图移动的情况
  • BeethOven:持续下拉底部scrollView 怎么能实现让父控件实现刷新?
    背靠背的微笑:你这个问题解决了吗?
    Everdinner:可以选择KVO监听处理,不过如果是一直下拉底部scrollView在回调上好像还是有问题,这个demo在临界处的处理由于具有手势冲突的存在还是不够完美,可以参考桌同学的做法给整个控件添加一个拖动手势:http://www.jianshu.com/p/040772693872
  • 木小土:如果在头部上拉的话,下方的view会停留住,这个问题楼主有什么好办法吗
    Everdinner:@木小土 这个可以同样根据上拉的距离使下面的scrollView滑动对应的距离,上拉刷新事件是根据contentOffset来触发的,如果你想达到最完美的控制效果可以考虑自己添加一个拖动手势来判断控制每个控件的滚动位置,桌同学的这篇博客可以参考一下:http://www.jianshu.com/p/040772693872
  • Passon_Fang:很棒棒:smiley:
    Everdinner:@DoubleFang 谢谢:smile:
  • Gavin_peng:楼主,我试了你的方法,有点小问题,比如那个JourneyListView中的TableView的代理,因为暴露在.h中,所以在ViewController中设置了它的delegate,如果此时再在JourneyListView内部设置TableView的代理时,内部的代理不会回掉,因为被外部的代理给屏蔽了,这样,就无法处理cell的点击时间了,楼主你是怎么实现的呢?
    Gavin_peng:@Everdinner 多谢楼主提醒,问题解决啦 :+1:
    Everdinner:demo中在viewcontroller设置代理只是为了展示效果,实际开发中可以在viewcontroller中设置JourneyListView中tableView的KVO来监听tableView的contentoffset来处理,将tableview的delegate设置在listView内部,而且tableview可以隐藏在JourneyListView内部,选择在.h文件添加一个方法来设置KVO监听tableview的滚动,希望可以帮到你,有问题随时交流
  • Kimball:scroview加scrollview加tableview,最底层的scrollview添加刷新,在tableView上滑动无发刷新
    Everdinner:@Kimball 你是添加的上拉还是下拉?
  • 阿拉灯神钉:哥们, 你这代码块没有设置成功呀
    阿拉灯神钉:@Everdinner :+1:
    Everdinner:@Jon_Snow 写这篇博客时默认还是富文本,所以显示还会有问题,现在已经改成MarkDown了,后面博客就不会有问题了
    阿拉灯神钉:@Everdinner 你用``` {代码块} ``` 这个没有设置好, 你查查啥原因
  • iChanne:为啥不用 container viewcontroller
    the_uncle:添加childVC的时候,怎么判断当前滑动的是childVC上的table还是父视图上的table
    这个昵称就很帅:我也遇到了这样的需求,实现方式跟你的一样,可是上下滑动不是很流畅(与单个scrollView相比)。现在想来,childViewController或许算是更优的选择。
    Everdinner:@iChanne 实际项目中嵌套的那三个列表视图最好是以child view controller添加,博客中只是为了方便举例
  • mengshuobuyi:顶部放headview,列表选择那块用sectionhead,下面用cell,不知这样可行否
    the_uncle:如果是在cell上添加childVC,那么vc的tableview或者collectionView的代理应该指定为谁呢
    the_uncle:@mengshuobuyi 你好 我用的也是你说的这个方法,是在cell上添加的三个chilidVC,但是滑动处理那里有点问题,方便的话,求个demo
    Everdinner: @mengshuobuyi 那个就是我提到的方法一,用tableview,一样可以

本文标题:UIScrollView嵌套UIScrollView的滚动处理

本文链接:https://www.haomeiwen.com/subject/mtatsttx.html