解决上拉加载更多,tableview抖动问题

本文章主要研究:scrollView的几个属性contentSize、contentOffset和contentInset的关系。并提供解决拉加载更多,tableview抖动问题的方案 。

概念

1.contentSize是scrollview可以滚动的区域,比如frame = (0 ,0 ,320 ,480) contentSize = (320 ,960),代表你的scrollview可以上下滚动,滚动区域为frame大小的两倍。

2.contentOffset是scrollview当前显示区域顶点相对于frame顶点的偏移量(向屏幕内拉,偏移量是负值。向屏幕外推,偏移量是正数),比如上个例子,从初始状态向下拉50像素,contentoffset就是(0 ,-50),从初始状态向上推tableview100像素,contentOffset就是(0 ,100)。

3.contentInset是scrollview的contentview的顶点相对于scrollview的位置,例如你的contentInset = (0 ,100),那么你的contentview就是从scrollview的(0 ,100)开始显示.

UIEdgeInsets的四个属性,如下:

typedef struct UIEdgeInsets {CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'} UIEdgeInsets;

分别代表距离上,左,下,右边的像素长度。

下面举个iPad例子:

(图1)

tableview初始化后,如上图所示,并打印了各个属性的值:

2015-04-01 19:43:00.501 xxx[2058:871144] contentInset:{64, 0, 56, 0}2015-04-01 19:43:00.502 xxx[2058:871144] contentOffset:{-0, -64}2015-04-01 19:43:00.503 xxx[2058:871144] contentSize{1024, 2037}2015-04-01 19:43:00.503 xxx[2058:871144] frame{{0, 0}, {1024, 768}}2015-04-01 19:43:00.504 xxx[2058:871144] bounds{{-0, -64}, {1024, 768}}

● 首先从contentInset分析,top=64,即NaviBar的高度,意思是从这儿开始显示tableview,而不是从(0,0)开始显示。

●那么contentOffset = -64也就不难理解了:当前显示区域顶点相对于frame的偏移量,即-64。你可以这么理解:它等同于从(0,0)下拉到了y = 64的位置。

●最后contentSize,宽度是iPad的屏幕宽度,而高度2037 = (cell.count 乘以 cell.height)。

●另外两个属性frame是提前设定的pad的屏幕长和宽,bounds则是{{-0, -64}, {1024, 768}}

设置contentInset的好处

有要求如下:tableview显示的区域是NaviBar和tabBar中间的区域,且tableView滑动通过NaivBar和tabBar的时候,仍可以透过背景显示,故设置contentInset可以达到此效果。如图:

(图2)

上图描述了两个场景:

1 初始化的时候,tableview顶头是NaviBar的下沿。

2. 向上推的时候,通过NaviBar的背景可以看到tableView。

仅仅设置tableview的frame是无法达到这个效果的。

解决上拉加载更多,tableview抖动问题

【问题描述】在一个自己实现加载更多的App中,当上拉操作的时候,从网络端下载下来数据,并更新tableview,如图loading所示:

(图3,上拉刷新,loading)

2015-04-01 19:04:16.078 xxx[2044:865035] contentInset:{64, 0, 56, 0}2015-04-01 19:04:16.079 xxx[2044:865035] setContentOffset:{-0, -64}2015-04-01 16:40:20.573 xxx[1869:836104] contentInset:{64, 0, 172, 0}2015-04-01 16:40:20.575 xxx[1869:836104] setContentOffset:{0, 1441}2015-04-01 16:40:20.789 xxx[1869:836104] contentInset:{64, 0, 56, 0}2015-04-01 16:40:20.792 xxx[1869:836104] setContentOffset:{0, 1325}从上面的log中可以看到,tableView初始化后,contentInset.bottom是56 top是64(恰好是tabBar和NaviBar的高度)。

● 然后出现contentInset.bottom =172,因为此时“加载更多”的view加到了tableview的末尾,所以contentInset.bottom +=“加载更多”的view.height ,最后即是172.

●最后,contentInset.bottom又恢复为56,这是因为“加载更多”的view隐藏了,tableview的ContentInset又恢复了,效果如上图3。

当“加载更多”获取数据下来,tableview更新后。由于contentInset从56—>172—>56。所以,会有一个抖动的现象:如下图4:

(图4)

从loading开始,加载更多后,“悄巴蜀”这个cell出来了,但是tableview先向下滑动,在向上滑动,产生了抖动现象。

【原因】当loading的时候,contentInset.bottom是172,当loading隐藏的时候contentInset.bottom = 56.这是因为在对tableview的contentInset赋值的时候,contentOffset也会相应改变。contentOffset的变化导致了抖动。

下面的log展示了,contentInset和contentOffset相关联的问题:

2015-04-01 16:40:20.573 xxx[1869:836104]contentInset:{64, 0, 172, 0}2015-04-01 16:40:20.575 xxx[1869:836104] setContentOffset:{0, 1441}2015-04-01 16:40:20.789 xxx[1869:836104]contentInset:{64, 0, 56, 0}2015-04-01 16:40:20.792 xxx[1869:836104] setContentOffset:{0, 1325}两次contentOffset的差值116,正好是contentInset的差值。【解决】tableview的contentInset还是要恢复的,但是contentOffset达到1441的较高值后,后面1325就可以忽略了。这样即可解决抖动

另外:当loading失败的时候,没有新的cell进来,会不会造成tableview末端悬空?我想去旅行,一个人背包,一个人旅行,

解决上拉加载更多,tableview抖动问题

相关文章:

你感兴趣的文章:

标签云: