背景介绍
APP中经常用到的一个场景,一个页面,可以 竖向 滑动,中间有个segment控件,支持 横向 滑动,横向滑动的scrollView上面又放了一个个可以竖向滑动的scrollView。
github地址:
https://github.com/oscarwuer/yhlinkagetableview
框架搭建
整个页面基于一个tableView,从上而下,分别是海报cell
,简介cell
,sectionHeaderView
,容器cell
。所以一共两个section,前一个section里有两个cell,后一个section只放一个容器cell。
由于最下面的也有三个tableView,为了区分开来,主页上的我们称为 mainTableView ,下面那三个称为 listTableView 。
sectionHeaderView
上放的是 HMSegmentControl 。
容器cell
是重点,上面放了个 UIScrollView ,横向摆放三个tableViewController的view。注意,是控制器的view。你也可以直接放三个tableView在scrollView上,然后你会发现你的cell里N多个if... else...
所以整体架构就是这样
原理实现
在介绍原理之前,有个函数需要认识下
1 | /* |
备注上解释的很清楚,第一个重点,我们需要写一个tableView基类,实现这个方法, mainTableView 继承自此基类tableView。
listTableView 就是普通的tableView即可。现在的效果是,滑动listTableView,mainTableView也会跟着滑动,所以现在需要做的是,当listTableView未滑动到顶的时候,禁止mainTableView的滑动。 核心就是在一定的时机,设置mainTableView的scrollEnabled为NO和YES 。此处为第二个重点
1 | - (void)mmtdOptionalScrollViewDidScroll:(UIScrollView *)scrollView { |
第三个重点,当listTableView滑动到顶时,需要发送 通知 告诉mainTableView,我已经到顶了,该你滑动了。其实就是改变两个bool值,因为在mainTableView的 scrollViewDidScroll
代理方法中,需要用来判断。
1 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { |
至此,功能大体上就完活了。不过还是有需要优化的地方,也就是第四个重点。当我们在横向滑动来切换segment时,有时候会触发使得纵向也滑动了,很不好的体验。所以需要在容器cell
中,横向滑动的时候,禁止纵向滑动
1 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { |
另外一个需要优化的地方,重点5,是当数据多的一页滑到中间,这时候切换segment,换到数据少的一页,向下拉动一点,再换回刚刚那个滑到中间的那一页(gif演示中最后一部分)。需要在容器cell
里做如下操作,否则会闪一下。
1 | - (void)setObjectCanScroll:(BOOL)objectCanScroll { |
最后一点,切记,mainTableView的bounces可以设置为NO,但是,listTableView的bounces一定得是YES,否则偏移量会有那么一丝丝误差使得滑不动。