【加载更多 Objective-C语言】

一、咱们上午就做了两件事儿,

1.把我们的数据,加载起来,

2.实现了下面这个”加载更多“按钮的功能,

按钮

3.只不过,我们加载数据的时候,用了一个自定义cell,

那么,基本加载数据的办法,我就不再说了,

基本,就是那些步骤,

只是把我们自定义cell部分,再给大家复习一下,

上午,我们在控制器里面,是不是有个数据源方法,

咱们上午,就是在我们这个数据源方法中,返回单元格的数据源方法中,

返回单元格

我们有这么四步,

1)第一步,获取模型数据,

2)第二步,创建单元格,

3)第三步,把模型,设置给单元格,

4)第四步,返回单元格,

只是在第二步,创建单元格的时候,以前是怎么创建的,

以前是直接UITableView *cell = 直接从缓存池里面取,如果不到的话,直接alloc init,这种方式创建,

然后,我们上午,创建cell的时候,就是用一个xib来表示,这里建了一个xib,在xib里面,拖拉拽,拽了这么一个cell,然后呢,设置一下这个cell的identifier,

重用ID

设置它这么一个重用ID,

然后,我们在代码里面,让这个拽好的cell,与我们新建的具体这么一个类型,这个自定义类型,

类型

自定义cell,相关联,

然后,这样的话,当通过xib,创建这个cell以后,就是创建这个类的一个对象,

然后,我们在这个控制器里面,我们用这个自定义的cell,调它的一个类方法,

类方法

调它的一个类方法,叫goodsCellWithTableView,

然后,在这个类方法里面,我们其实就是干什么呢,

干什么呢

其实,就是封装了一个通过xib,创建cell,的这么一个代码,

通过xib,创建cell的代码,就是,

1)首先,获取我们的根目录,在根目录里面,调它的loadNibNamed,这个方法,加载这个xib,@“CZGoodsCell”,

2)然后,这个方法,会返回一个数组,在这个数组当中,我们取得第一个对象,或者最后一个对象,就是我们这个xib里面,这个cell吧,

cell

因为,这个xib里面,只有一个cell,所以说,获取到的就是这个cell,

OK,这样的话,在控制器里面,就可以自定义一个cell了,

拿到这个cell,

cell

拿到这个cell以后,然后我们基本上上面这个滚动,就做完了,

滚动

上面这个数据,就做完了,

2.然后,接下来,我们就实现一个“加载更多”,

“加载更多”,它首先是在我们tableView的tableFooterView里面,

有一个“加载更多”,

因为,这个“加载更多”里面,不仅仅是一个按钮,

里面是不是有可能,有一些其他的一些控件吧,

控件

所以说,我们这里,footerView里,要加一个UIView,

在UIView里面,再放一些其他的子控件,而不是下面只是一个按钮,

所以,我们这个时候,就发现,footerView,“加载更多”,这块儿代码,这个块儿内容,是不是也可以使用一个xib来描述啊,

所以,我们就又建了一个xib,

建了一个xib

我们建两个xib了,

1)一个是描述单元格的一个xib:CZGoodsCell.xib,

2)一个是描述footerView的一个xib:CZFooterView.xib,

单元格
footerView

一个是描述单元格的xib,

一个是描述footerView的xib,

1)在这个xib里面,首先我们就拽了一个“加载更多”按钮,

2)然后,我们又放了一个,用来显示等待信息的View,

等待

3)然后,我们通过拖线的方式,让两个属性和它相关联,

两个属性

这里,两个属性,一个是btnLoadMore,一个是waitingView,

让这两个属性,分别和我们这个View,和上面按钮相关联,

设好关联以后,我们接下来,为我们这个“加载更多”按钮,注册单击事件,

这就是“加载更多”按钮的单击事件,

单击事件

3.在这个单击事件里面,

1)首先,第一步,就是让我们,当点“加载更多”按钮的时候,就让“加载更多”按钮隐藏掉,

2)第二步,让waiting,那个“等待指示器”,显示出来,

3)第三步,更新数据,

但是我们发现,更新数据,其实就是创建新的model,把它加到那个数据集合里面,就可以了,但是我们在footerView里面,发现在这里是访问不到,无法访问到我们这个控制器里面这个goods集合的,

goods集合

所以说,这个时候,就遇到一个问题,你在footerView这个自定义的一个View里面,想访问控制器里面那个集合,但是访问不到,这个时候,我们首先想到的就是什么,代理吧,

那么,在用代理之前,我们基本的思考方式,就是

1)首先,想现在要为谁找代理,footerView吧,

footerView

现在是不是要为footerView,是不是要为它找代理,

因为它想做一件事儿,它自己干不了,所以这个时候,它就看一下,谁能干了呢,因为那个goods集合是在我们的控制器里面,所以说,它发现,控制器能做这个事儿,所以说,这个时候,就找谁作为它的代理,控制器吧,

然后,到此为止,我们就分析出了,现在是谁要找代理,然后呢,让谁作为它的代理,那么就是footerView,它要干一件事儿,它干不了,所以,它要找代理,这件事儿,谁能干了,控制器能干了,所以说,让控制器作为它的代理对象,所以说,谁找代理,谁是代理,这两个就已经确定了,

然后,接下来,就是哪个控件要找代理,是不是要为这个控件,写一个代理协议啊,

2)写代理协议,现在就是,CZFooterView,这个控件要找代理,所以说,就在这个控件的头文件里面,新建这么一个,定义这么一个协议,

协议

这个协议就是,为这个控件,CZFooterView,代理而生的一个代理协议,就是这个控件的一个代理协议,

一般命名规则就是,控件名后面,跟一个Delegate,

控件名后面,跟一个Delegate,就是这个控件的一个代理协议,

然后,写好代理协议以后,就是

3)代理协议里面这个方法,叫什么,

这个方法的命名规则就是,这个代理协议是哪个控件的代理协议,前面就是控件名,当然,去除那个前缀,控件名,后面加一个具体的方法名称,

然后,一般情况下,你为控件写代理,这个代理方法中,一定会有一个参数,这个参数就是,哪个控件写代理,这个参数就是对应的控件,

现在,我们的footerView,要找代理,所以说,为它写好了一个代理协议,

写好一个代理协议以后,紧接着,第二步,就是

4)为我们控件,加一个delegate属性,

delegate属性

为控件,加一个delegate,这个属性,

这个代理这个属性,一般名称就叫delegate,这是我们的约定,

然后呢,还有就是我们这个属性里面的类型,就是id类型,同时要用一个协议来约束一下,

id< CZFooterViewDelegate >

它必须是遵守这个协议的,

然后,我们的自定义控件里面,就是写代理,就基本写完了,

这里创建代理协议,这里有个代理属性,

然后,紧接着,就是自定义控件里面,什么时候要用到这个代理对象呢,在这个CZFooterView.m文件中,

5)当我们点击“加载更多”的时候,

代理

接下来,是不是要调我们代理里面的这个方法,footerViewUpdateData:

来更新tableView的数据啊,

所以说,接下来,我们就是要用一下代理,

自定义控件里面,

1)第一,写代理协议,

2)第二,增加一个代理属性,

3)第三,使用代理,

在这个地方,首先判断,当前这个代理对象里面,是否有这个方法,

方法

如果有这个方法,调一下当前这个footerView控件自己的delegate属性里面的,这个footerViewUpdateData:,方法,把当前footerView,自己传进来,

[self.delegate footerViewUpdateData:self];

这是不是就是使用代理,

使用代理

这,就是使用代理,

那么,现在我们基本上这个footerView控件就写完了,

那么,它写完以后,要想用代理,是不是你得先给它设置一个代理对象啊,

3.所以说,这个时候,就找到我们控制器,

控制器

控制器这儿,viewDidLoad里面,在我们控制器的这个View加载完毕以后,接下来,我们就在这里,创建了一个footerView,

创建footerView

通过xib来创建footerView,

通过xib,创建好了这个footerView,

接下来,设置当前这个footerView控件的代理对象,等于控制器自己,

然后,我们就可以把footerView这个控件,设置给当前tableView的这个tableFooterView的这个属性了,

然后,footerView里面,就有这个我们自己写的这个footerView控件了,

控件

然后,我们运行起来之后,你再点击“加载更多”,加载更多按钮被隐藏,同时显示“等待指示器”,同时“驴肉火烧”被显示出来了,

##火烧

基本上,我们上午就说到这儿了,

二、我们希望的是,当点击“加载更多”的时候,这里显示这个“驴肉火烧”,同时,这个是不是要转一下,应该是这个转一下,然后是不是再显示这个“驴肉火烧”,

1.显示完毕以后,接下来,这个东西,是不是要再隐藏掉,等待指示器,再隐藏掉,

“加载更多”按钮,是不是再显示回来,

那么,这个操作,在哪儿写呢,

还是找到我们这个footerView,

footerView

我们希望是,一开始先隐藏”加载更多“按钮,

显示等待指示器,

然后呢,开始刷新数据,

先判断一下,代理是否实现了代理方法,footerViewUpdateData:

如果实现了代理方法,则调用代理方法

[self.delegate footerViewUpdateData:self];

然后,接下来,数据刷新完毕以后,把这两个再给它显示回来啊,

把“加载更多”按钮,再显示回来,

把“等待指示器”,再隐藏回去,

但是大家想,我如果这么写,对不对,

这么写

这么写大家觉得对不对,序号改一下,

序号

这么写,大家觉得对不对,NO,和YES,改一下,

序号

这样写是不对的,为什么,

这样写,你其实看不到效果的,

因为,你一开始,让它隐藏(加载更多按钮),让它显示(等待指示器),执行完这句代码,是不是紧接着,立刻执行这段代码(让加载更多按钮显示,让等待指示器隐藏),

相当于,你刚刚把它隐藏(加载更多按钮),把这个显示(等待指示器),然后呢,后来又把第一个显示(加载更多按钮),又把第二个隐藏(等待指示器),

是不是在很短很短的时间内,是不是它又恢复到原来的状态了,

所以,这样写,是不行的,

那么,我们为了模拟这个效果,是不是需要让它隔一段时间以后,再执行这段代码(让加载更多按钮显示,让等待指示器隐藏),

如果你希望,隔一段时间以后,再执行另外一段代码,这个时候就可以使用,dispatch,

5.隔一段时间再执行代码,dispatch,

隔一段时间

注意,dispatch,是不是又这么多个dispatch啊,

用哪个呢,就找这个GCD的,

记的时候,你就记住,第一个单词是dispatch,后面有个GCD,

这些看都别看,直接选这个,

直接就选这个,然后回车,

回车

选GCD的dispatch

直接就选这个GCD的dispatch,

然后这个地方,注意这个delayInSeconds,

延迟

这个就是延迟多少秒以后,执行,延迟多少秒以后,我们希望它延迟1.0秒钟以后,

1秒钟

延迟1.0秒钟以后,

延迟1.0秒钟以后,执行什么呢,

code to be executed after a specified delay,

在一个指定的、特定的,延迟以后,要执行代码啊,

我们这个,在1.0秒钟之后,然后再开始,加载我们的数据,

延迟

别一点它(“加载更多”按钮),立刻就把那个“红烧肉”显示出来,好像给人感觉很假的样子,其实本来就很假,但是我们为了模拟的像一些,

所以说,当点完“加载更多”以后,在1秒钟之后,我们再执行这个代码,

执行这个代码,是不是调用代理,调用代理,是不是把那个tableView的数据是不是刷新出来了,数据刷新出来了以后,紧接着,然后再把这两个按钮、这两个控件,恢复到原来的状态,让“加载更多”按钮显示,隐藏“等待指示器”,

隐藏

这就是,当你点击这个按钮的时候(btnLoadMore),

加载

1)首先要“加载更多”按钮隐藏,

2)让我们下面“等待指示器”显示,

3)隔一秒钟之后,刷新一下tableView,

刷新

给它增加一条新数据,当新数据增加完毕以后,

4)再把“加载更多”按钮,让它显示,

5)再让“等待指示器”隐藏,

运行一下看看,它会不会等待一秒钟,

等待

是不是等待一秒钟了,

这个是不是也回来了(加载更多按钮),

这是不是就是这个效果吧,

这就是我们“加载更多”,模拟这么一个效果,

大家记这个dispatch的时候,你就先记dispatch,后面有个GCD,

用这个就OK了,

用这个,直接就双击,双击完毕以后,第一个参数,这里写的是,时间间隔,不是间隔,是“等待1秒钟”之后执行,里面的这个代码,

代码

ok,这就是我们这里所说的这么一个延迟,

好,然后,紧接着我们再看一下,这个地方,

二、我们这个创建这个footerView,

footerView

1.我们这里创建这个footerView的代码,大家觉得有问题吗,在ViewController.m文件中,

我们这里创建这个footerView,这个代码,是不是直接通过xib,加载footerView的代码,是不是直接写在这个地方了,

把通过xib加载footerView,的代码,直接写在这里,

这样写好吗,不好,有什么不好,

还是那两个原因,

1)如果说,我有100个地方,用到了这个footerView,我是不是在100个地方,得手动去加载一下xib,是不是,这是第一个问题,

2)第二个问题是,你这个封装的不够,那么现在这个footerView,是通过xib来写的,可以这么写,一旦你footerView,它不再通过xib来创建了,这个时候,你把这个代码一改,是不是100个地方都得改,

因为100个地方,都是直接通过xib来加载的啊,

所以说,我们还是希望封装一个类方法,那么把这个通过xib加载这个自定义控件的代码,封装到这个类方法里面,

然后你需要用到这个footerView的地方,直接调这个类方法,创建一个footerView,就OK了,

就是,把这个也是封装到一个类方法里面,

把通过xib创建footerView控件的代码,封装到一个类方法当中,

CZFooterView *footerView = [[[NSBundle mainBundle] loadNibNamed:@“CZFooterView” owner:nil options:nil] lastObject];

代码

2.所以说,我们把这个代码,再给它封装一下,来,找到我们的这个footerView,找到CZFooterView.h文件,

封装

来一个类方法,+ (instancetype)footerView;

类方法

实现一下,在CZFooterView.m文件中,

实现

+ (instancetype)footerView{

//在里面,其实很简单,就是通过xib,创建一个footerView,然后把它返回,

CZFooterView *footerView = [[[NSBundle mainBundle] loadNibNamed:@“CZFooterView” owner:nil options:nil] lastObject];

return footerView;

}

类方法

有人说,你这里面不就也是这句话吗,对,也是这句话,但是,你如果这么写的话,在控制器里面,调的时候,就没有必要这样调了吧,

控制器

是不是直接调它的类方法,就OK了,

CZFooterView *footerView = [CZFooterView footerView];

类方法

然后,如果说,哪一天,这个xib,这个footerView不是根据xib来创建的,你只要把footerView里面,把这个方法中的代码,改了就OK了,

类方法

对于控制器来说,控制器的这儿的代码,需要改吗,不需要吧,因为它是不是调这个方法去了,

调

这样就达到了,当需要修改的时候,只需要修改你特定的地方,不需要修改项目中其他的地方,

修改

这样就尽量降低了耦合度,控制器就不会依赖于,对应的这个footerView了,footerView的改变,不会影响控制器的代码,这是我们的一种设计思想,

所以说,我们把footerView这里,再做一次封装,

好,到此为止,我们这个加载更多,也OK了,

三、然后,这里再给大家提一点,在我们这个代理方法当中,

1.找到控制器里面这个代理方法,控制器里面,有个footerView这个代理方法,

控制器
代理方法

在控制器的这个代理方法当中,

我们是不是,

1)首先,创建了一个模型,

2)然后,把模型加到了这个集合当中,

3)然后,刷新了一下tableView,

刷新tableView,我这里调的是什么方法,调的是reload,方法吧,

reload,方法,是不是直接刷新整个的tableView,

那么这个时候,大家可能会想到,还记得咱们昨天说过两种刷新tableView的方法吗,是不是那个是局部刷新,只是刷新某一行吧,

修改了某一行,就刷新某一行,

大家觉得,这个时候,用那个好,还是用这个好,

为什么用这个好,

我觉得用那个好吧,那个只是刷新一行,这个是刷新整个数据啊,

我们这里其实不是说用哪个好的问题,那个就不能用,

只能用这个,

只能用这个

只能用这个,reloadData,

为什么呢,

咱们昨天说过,那个reloadRows,是不是那种刷新方式,只适用于总行数没有发生变化的情况下吧,

就是说,一开始是10行,然后呢,比如说我们昨天是有个“暴走萝莉”,咱们把它的名字给它改成“暴走”了,

那行,一开始就有那行,我只是把那行里面的内容改了,

那么,整体上,UITableView,整体的行数,是不是没有变啊,

UITableView的总行数没有变,

在这种情况下,是可以使用reloadRows,那个方式的,

就是,总行数没有发生变化,只是改了某一行中的内容,

如果说,总行数发生了变化,比如说,原来是10行,你LoadMore,是不是又增加了几行,

又增加了几行,tableView中的总行数,发生变化了吧,

当它的总行数,发生变化了以后,就不能使用这个reloadRows,局部刷新,必须使用reloadData,整体刷新了,

如果我这里,偏偏就要使用局部刷新的话,我们看看会报一个什么错,为什么会报这么一个错误,

局部刷新

//局部刷新(只适用于UITableView总行数没有发生变化的情况)

这里依然是调用tableView,对象的reload,不是Data,

局部刷新

self.tableView reloadRowsAtIndexPaths : (NSArray *) withRowAnimation : (UITableViewRowAnimation)

局部刷新

这个里面,首先,需要一个数组,这个数组,是不是你要刷新哪些行吧,

是不是把那些行对象,给我啊,

这里,你要刷新的那些行,我们都用indexPath,来封装吧,

就是第几组的第几行,这里,其实就增加了一行,这里只增加了一行吧,

增加一行

这里是不是传一个对象过来,就可以了,

但是,我们是不是得创建一个组对象,

怎么创建,还记得吗,

NSIndexPath *idxPath = [NSIndexPath indexPath

创建组对象

是不是有一个类方法吧,

indexPathForRow,

第几个section

第几个section,呢,我们这里是不是只有1组,

是不是第0个section,

section

然后,第几行呢,是不是最后一行,

是不是始终是最后一行,我们新加新行,是不是始终在最后一行,

最后一行,怎么获取最后一行,

当前,集合中,有多少条数据,

self.goods.count,

count,减去,1,

是不是就是最后一行的索引,

self.goods.count - 1 ,

如果当前是10条,最后一行的索引,就是10 减 1 ,就是几,9 吧,

所以说,这是不是就拿到了最后一行的行对象啊,

行对象

然后,把它写在这个里面,

行对象

然后,后面这个参数,需要动画吗,

UITableViewRowAnimation,

UITableViewRowAnimationLeft

UITableViewRowAnimationLeft,

Left

这样的话,是不是通过一个动画的方式,来刷新,

咱们试试,看我现在能不能使用这个东西,

能行吗

能行吗,报错了吧,咱们看一看,报了什么错,

上面,这一堆,你需要看吗,

需要看

根本不需要看,只看哪里,

看

只看这个,reason,吧,

reason,是不是出错的原因吧,

只看这个reason,看一下这里告诉你,

attempt to delete row 13 from section 0 which only contains 13 rows before the update,

尝试去删除,索引为13,的这一行,从第0组,里面,尝试去删除,13这么一行,但是呢,这个组里面,仅仅只有13行,在你更新的时候,仅仅包含13行,

什么意思呢,

一开始,这个section里面,有13个商品吧,13个商品,最大的索引,是多少,12,最大的索引是12,

它这句话的意思是,通过这个局部刷新,

其实它局部刷新,是啥意思啊,

比如说,你想把这个“将太无二”,改成“将太无三”,

将太无二

当你点它,是不是弹出一个对话框,把“将太无二”,改成“将太无三”,了,

改成“将太无三”,当点“确定”的时候,如果你是通过局部刷新,来更新,这个时候,其实它的意思是,

先把“将太无二”,原来的旧行给它删掉,然后创建一个新的cell,把这个新的cell,给显示过来,

它这个刷新,是这个意思,

先把旧的删掉,再把新的给你刷新过来,

而那个reloadData,

全部刷新的意思是,直接把这个tableView,就不要了,

全都重新创建一个,

而局部刷新,它是先把旧的行,删掉,然后再把新的单元格再给你创建一个啊,

是这么来做的,

如果你是把“将太无二”,改成“将太无三”,

因为这行本来就存在,

你也不用把它删掉,

总行数没有变,

只是把它的内容改了,这时候,没有问题,把旧行删掉,来一个新行,

但是,当你加载更多,的时候,它这个时候,是不是要加一条新数据啊,

加一条新数据,本来是13行,加一个新数据以后,应该变成14行了吧,

变成14行,但是,只有当我们这个reloadRow,或者局部刷新,调用完毕以后,这个界面上,才会有那个第14行啊,

当局部刷新方法调用完毕以后,界面上才会有第14行,

但是,它在刷新方法里面,它就会尝试,先把第14行删掉,它会找索引为13的行,把它删掉,然后它会再给它加一个新行,

但是,这个方法,还没有调用完毕,整个UITableView里面,现在是不是只有13行,最大的索引是12,

那么也就不存在索引13,

当你刷新完毕,才存在索引为13的这行,

所以说,一开始,在调这个方法的时候,UITableView上,只有13行,

最大的索引是12,这个时候根本就没有这个索引为13的行,所以,你这个时候,尝试去删索引为13的行,它就告诉你,你尝试去删除第0组里面,第13、索引为13的行,但是,第0组里面,只有13行啊,

在你更新之前,只有13行啊,

最大的索引,是12,

所以报错了,

局部刷新,当我们的行发生变化、UITableView的总行数发生变化的时候,还能调这个局部刷新吗,不能了吧,

局部刷新

好,所以我们这个时候,就不能调这个局部刷新了,

局部刷新

还是可以选择上面这种方式,

[self.tableView reloadData];

上面

当然,我们也有一些其他办法,比如说,我们可以调insert,方法,

给它在界面上,手动插入一行,

这样也行,今天我们就先介绍这么一个,

就是刷新,这个效果,

就是用这个reloadData,全部刷新,

四、还有一个小问题,点加载更多,注意看,

加载更多

点完以后,

点完以后

看到了吗,它是在这里,

在这里

希望点完以后,它立刻变成这个效果,

点完

点完以后,它再向上滚一下吧,

把这个再滚出来,

不然是不是还得手动滚一下,

我希望点完以后,你把这个“驴肉火烧”加载出来,同时是不是再向上滚一下,滚到这个地方,能显示出来“加载更多”吧,

2.要实现这个效果,就需要我们手动,我们说,TableView,默认,我们是不是只能通过手指,或者通过鼠标键,这样来滚动啊,

但是,我希望通过程序来让它滚动,

让我们最后这行数据,滚上来,

滚

2.在ViewController.m文件的footerViewUpdateData:,方法中,

当数据刷新完毕以后,我们这里再来一步,

//5.把UITableView中的最后一行的数据滚动到最上面,

滚动

怎么来滚呢,我们希望让谁滚,是不是UITableView来滚,

所以,我们就找到这个tableView,对象,

tableView

[self.tableView

滚动,大家猜猜是哪个单词,scroll,吧,

滚动

scroll,什么,scrollTo,scrollTo哪里,

scroll

scrollToRowAtIndexPath,

这个方法,

滚动到指定的行, 滚动到指定的行,

我们是不是希望,滚动到最后一行吧,

滚动

所以说,我们这里是不是要拿到最后一行,这个行对象,

行对象

NSIndexPath *idxPath = [NSIndexPath indexPathForRow:self.goods.count - 1 inSection : 0];

这是最后一行,拿到最后一行,

最后一行

把最后一行,传到这个地方,

最后一行

[self.tableView scrollToRowAtIndexPath:idxPath atScrollPosition:

(UITableViewScrollPosition) animated:(BOOL)];

它把最后一行,滚到什么位置呢,是不是需要动画呢,YES,吧,

动画

来,看一下,我们滚动,让把最后一行,滚到什么位置呢,

这里有一个Position,

Position,就是位置,

那么,这里把这个最后一行,滚到什么位置呢,

看,UITableViewScrollPosition,

一看就是个枚举,没有星号,对吧,

哪个

哪个,

1)Bottom,

2)Middle,

3)None,

4)Top,

是不是把它滚到最上面啊,

最上面

把当前这行,滚到最上面,

运行一下看看,对不对,

对吧

对吧,

首先,是不是实现我说的那个效果了,把这个显示出来了,

但是,这个时候,大家可能会问一个问题,

你不是说把它滚到最上面吗,Top,

你看它到最上面了吗,

哪里是最上面,

最上面

这才是最上面呢吧,

它其实是可以到最上面的,但是因为你后面还有数据吗,

你后面没数据了,它有必要滚到最上面吗,

没有必要,

所以说,我们这儿,我如果选的是这个“俏巴蜀”的话,

滚动

它就会把“俏巴蜀”滚到这里,

滚动

因为它是可以滚到这儿的,

因为,最后一行,滚到最上面,就是滚到这里了,

你尝试继续往上滚,

滚动

但是发现,后面没有数据吧,

没有必要滚到这个地方,

那大家来,给大家看一下那个Middle,

中间

来,看一下Middle,是什么效果,

效果

滚到中间,是不是也行吧,

滚动

但是滚到Bottom,行吗,

Bottom

是不是滚到最下面,

Bottom

它本来就在最下面啊,

是不是还得再往上滚,才可以啊,

ok,所以说,这个意思,

所以说,直接让它滚到最上面,

不跟它废话,直接滚到最上面,

ok,这就是我们这儿的一个,把它加载完毕以后,再向上滚一下,

这是我们这儿说的这么一个效果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风清晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值