之前大家应该用过MJRefresh或者SVPullToRefresh上下拉刷新框架,如果要我们自己编写一个类似的普通适应性强的框架可能会稍有困难。此处本文便分别给出上拉刷新和下拉刷新的编写思路,如果有什么问题可以给我留言或私信。我这里用我写的一个demo(CLRefresh)来分析。
一 思路简述
常见的需要添加上下刷新的地方便是UITableView和UICollectionView了,我们在编写这些功能时并不复杂,主要便是:1 给他们添加一个头视图和尾视图;2 根据他们的偏移量来判断是正在刷新,还是刷新完成,亦或者是拉动幅度过大等等。为了扩大该种控件的使用广泛性,我们在基于UIScrollview的基础上添加这些特性(因为UITableView和UICollectionView的父类都是UIScrollview),最好的实现方式则是用UIScrollview的分类来实现上下拉刷新功能。
那么又如何来编写UIScrollview的分类呢?最好的方式便是给其添加两个新属性header和footer,然后再根据UIScrollview的偏移量来决定上拉控件和下拉控件运行状态。
二 上拉刷新的实现
本文例子CLRefresh中可以这样使用:
进入 -(CLPullHeaderV*)cl_addPullRefreshControlWithBlock:(void(^)(void))refreshBlock{ 该方法,可以看到如下图:
该方法主要便是给UIScrollview添加了一个CLPullHeaderV的头视图,该头视图即可以在下拉时显示出来,这里还对UIScrollview设置了一个关联对象(即头视图)。
打开CLPullHeaderV类可以看到
该类中有一个最重要的状态枚举类型CLRefreshState,三种状态如注释所示。并且该类还拷贝了一份cl_PullRefreshHandler的block对象。该类中对UIScrollview对象也进行了监听:
监听UIScrollview的contentOffset 是为了处理下拉控件的显示状态,而监听frame是为了及时的刷新视图布局。
监听contentOffset是下拉刷新最核心的工作,处理逻辑如下所示:
而对于转态的设置又可以从下图看到处理方式:
其中当设置为CLRefreshStateLoading时,即执行cl_PullRefreshHandler(传入的block)回调操作。
以上便是下拉刷新的核心处理逻辑,具体可以参见demo。
三 上拉加载更多
本文CLRefresh例子中这样使用:
进入-(CLUpFooterV*)cl_addUpRefreshControlWithBlock:(void(^)(void))refreshBlock{方法可以看到:
该方法中依旧是添加了一个CLUpFooterV的尾视图给UIScrollview上。进入该CLUpFooterV,可以看到
其中有一个上拉的枚举类型CLRefreshUpState,分别为“ CLRefreshUpStateStopped,//正常 CLRefreshUpStateLoading,//加载中 CLRefreshUpStateTriggered //即将触发 ” 这三种状态,这些状态便是下拉控件根据UIScrollview的偏移距离来决定的。所以该尾视图也需要对UIScrollview的进行监听:
监听contentOffset是为了改变上拉控件所处的状态,而监听contentSize是为了 当UIScrollview的理论大小发生改变时可以将尾视图的位置也进行调整至UIScrollview的底部位置。具体的监听处理方法如下:
-(void)scrollViewDidScroll:(CGPoint)contentOffset{ 该方法是上拉处理的核心部分。当该下拉控件所处的状态为“CLRefreshUpStateLoading”,则不进行如何处理,否则 当手指向上拉动UIScrollview的偏移量超过临界值scrollOffesetThreshold,即把该状态调整为CLRefreshUpStateTriggered“控件可触发状态”;当手指释放时,如果控件可触发,则状态再次更改为CLRefreshUpStateLoading“加载中状态”,否则为“CLRefreshUpStateStopped” 停止状态。 之后对于每种状态的设置如下所示:
该方法中可以看到,如果先前的状态是“CLRefreshUpStateTriggered”,而当前状态是“CLRefreshUpStateLoading”,则执行cl_UpRefreshBlock的回调block方法,该block执行完后再将上拉控件的状态调整为“CLRefreshUpStateStopped”停止状态。
以上便是CLRefresh实现的简单思路,具体编写可以参考github,如果您有什么问题可以私聊我或留言,如果能获得您的star则倍感荣幸。