【转载请注明出处】html
本文将说明具备多个section的UITableView在使用下拉刷新机制时会遇到的问题及其解决方案。git
工程地址在帖子最下方,只须要代码的直拉到底便可。github
【目录】post
一、现象分析;ui
二、解决方案;url
三、工程地址。 spa
一、现象分析
当前的大多数支持下拉刷新的库,都是经过修改UIScrollView的contentInset实现的。3d
(可参见个人这篇帖子:UITableView:下拉刷新和上拉加载更多)code
使用这种方法带来的问题是,当UITableView具备多个section时,依照上述方式使用下拉刷新,在加载过程当中上滑,会出现样式跑版:htm
为了分析出问题所在,首先在控制台打印出正常状态下UITableView的全部子View :
比较各行的frame.origin.y能够看出,UITableView的section headerView是和cell一块儿,按顺序放入基类UIScrollView的内容View中的。
再看加载中时的状况:
从Pull2RefreshView的frame能够看出,此时UITableView的contentInset已经被修改成(65, 0, 0, 0)。而section headerView和各个cell的frame.origin.y不受影响,和预期一致。
最后看看在加载中状态下上滑时的状况,将UITableView上滑至上方图中所示情境,即第一行的cell刚恰好越过section headerView:
能够看到,section headerView的frame.origin.y发生了变化,它和第二个cell一块儿被放在了第一个cell的下方,即:
section headerView.frame.origin.y == firstCell.frame.origin.y + cellHeight;
继续上滑,能够看到section headerView.frame.origin.y不断变化,但在界面显示上,始终位于距离UITableView.frame.origin.y为65(即修改后contengInset.top的值)的位置,直到下一个section headerView出现时,才随着cell向上移动,如图:
【注意:不论在任何状况下,第一个cell的frame.origin.y始终为section headerView的高度,在本例中为23,即便它已经处于section headerView的上方】
二、解决方案
由此,能够粗略得出如下结论:
A、 section headerView和cell之间并非简单的顺序摆放的关系,它们之间能够发生重叠;
B、 section headerView在界面上的显示位置由UITableView.contentInset.top决定,直到被下一个section headerView替代。
如此,想要在滑动时修改section headerView的显示位置,令其和cell一块儿移动,只须要动态地修改UITableView.contentInset.top便可,以下:
Added 2014.7.24:
对于不须要提交到AppStore的应用,还有一个更简单的办法,即覆盖UITableView的私有方法。
- (BOOL)allowsHeaderViewsToFloat { return NO; } - (BOOL)allowsFooterViewsToFloat { return NO; }
三、工程地址
使用iOS 6.1 SDK编译,使用ARC。
地址:https://github.com/cDigger/CDPullToRefreshDemo
【参考】
一、Section Headers in UITableView when inset of tableview is changed
二、Change Default Scrolling Behavior of UITableView Section Header