先来整体效果图给以说明
页面整体结构是一个大的滚动视图嵌套了三个可以滚动的子视图,起初在做这种效果时,搜了一下网上并没有找到合适的解决方案,于是在自己动手实现后拿出来分享一下,如果你在开发中也遇到了产品提的这种奇葩需求,相信这会是一个不错的解决方案,希望对大家有帮助!(由于是示例,效果就差那么几丢丢了~)
首先我们分析一下这个效果的几种实现方案:
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。
最后,如果你有更好的实现原理和解决方案,希望能告诉我,共同学习!