日常用的刷新用是开源的MJRefresh,这个刷新库想必也是不少开发者比较熟悉的一个库,做者采用继承的方式,不一样的层次有不一样的功能与UI展现,用起来简洁,方便。bash
MJ为UIScrollView类写了类别,给UIScrollView增长了mj_header
(下拉刷新)和mj_footer
(上拉加载更多)两个关联对象。 MJ做者李明杰老师的示例用法以下:网络
__weak typeof(self) weakSelf = self;
self.tableView.mj_header = [MJRefreshHeader headerWithRefreshingBlock:^{
[weakSelf refreshAction];//这里能够作请求网络等操做。
}];
刷新的操做结束后,调用下边方法,结束刷新
[self.tableView.mj_header endRefreshing];
复制代码
__weak typeof(self) weakSelf = self;
self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
[weakSelf footerRefreshAction];//请求更多数据
}];
//能够根据请求的结果来以不一样的方式结束刷新。
[self.tableView.mj_footer endRefreshing];
[self.tableView.mj_footer endRefreshingWithNoMoreData];
复制代码
以上只是示例,MJ中做者提供来多种不一样UI和交互的header和footer供你们选择使用。ui
日常这样直接按照做者的Demo示例用能够,可是我的总以为不太好。就想着可以封装下(主要是懒,想省点事)。atom
先说下基本的需求:一个tableView的列表,每页请求20(注:不一样的公司可能不一样的每页条数,这里只是举例)条数据,下拉刷新的时候是从新请求第一页的数据,上拉加载更多的时候是请求下一页数据。若是下一页数据仍是20条,则认为还有数据,将footr以正常的状态结束刷新。再次上拉加载的时候,还会正常请求下一页的数据。 若是加载出来的数据少于一页的数据条数(20条),那么就认为没有更多数据了,这时就将footer以没有更多数据的状态结束刷新,再进行上拉加载的时候,将不起做用。spa
我想要的效果是,我外部调用的时候,我只想知道触发去请求刷新和加载更多的时机, 其它的都不想管。code
本人目前的实现是:给UITableView写了一个类别(UICollectionView同理。UIScrollView也能够进行下拉刷新,只不过是不用上拉加载更多了)。写了两个方法,分别是下拉刷新和上拉加载的调用。同时增长了两个关联对象:每页的数据条数和一个上拉加载更多后的footer的设置回调的block。 示例代码以下:orm
#define WeakSelf __weak typeof(self) weakSelf = self;
typedef void(^FooterConfigBlock)(NSInteger newDataCount);
typedef void(^RefreshActionBlock)(FooterConfigBlock footerConfig);
@interface UITableView (Refresh)
/**
每页的数据条数
*/
@property (nonatomic,strong)NSNumber *pageCount;
/**
设置footer的回调
*/
@property (nonatomic,copy)void(^footerConfigBlock)(NSInteger newCount);
/**
header的刷新
@param refreshBlock 刷新的回调,回调block里有个"FooterConfigBlock"的参数,外部调用的时候能够将请求下拉的数据的条数传进来,让方法里边对footer进行设置。eg:若是下拉刷新都没有数据的话,就能够直接将不要footer。
*/
- (void)normalHeaderRefreshingActionBlock:(RefreshActionBlock)refreshBlock;
/**
footer的刷新加载更多
@param footerRefreshBlock 加载更多的回调。回调block里有个"FooterConfigBlock"的参数,外部调用的时候能够将请求下拉的数据的条数传进来,让方法里边对footer进行设置。eg:若是上拉加载返回的数据小于每页的设置条目数量,则认为数据已经加载完毕,能够将footer设置为没有更多数据的状态。
*/
- (void)backNormalFooterRefreshingActionBlock:(RefreshActionBlock)footerRefreshBlock;
@end
@implementation UITableView (Refresh)
#pragma mark --关联对象----------------
- (void)setPageCount:(NSNumber *)pageCount
{
objc_setAssociatedObject(self, @selector(setPageCount:), pageCount, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)pageCount
{
return objc_getAssociatedObject(self, @selector(setPageCount:));
}
- (void)setFooterConfigBlock:(void (^)(NSInteger))footerConfigBlock
{
objc_setAssociatedObject(self, @selector(setFooterConfigBlock:), footerConfigBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void (^)(NSInteger))footerConfigBlock
{
return objc_getAssociatedObject(self, @selector(setFooterConfigBlock:));
}
#pragma mark --header刷新----------------
- (void)normalHeaderRefreshingActionBlock:(RefreshActionBlock)refreshBlock
{
//若是外部调用的时候不设置每页的数据条目数量pageCount。这里设置一个默认值。
self.pageCount = [self.pageCount integerValue] > 0 ? self.pageCount : @(20);
WeakSelf
//将外部的block给关联对象赋值,若是外部须要内部进行footer和header结束刷新的处理的话,能够传block进来。
self.footerConfigBlock = ^(NSInteger newCount) {
[weakSelf handleEndRefreshing:newCount];
};
self.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
refreshBlock(weakSelf.footerConfigBlock);
}];
}
#pragma mark --footer刷新----------------
- (void)backNormalFooterRefreshingActionBlock:(RefreshActionBlock)footerRefreshBlock
{
//同理设置一个默认的每页数据条目
self.pageCount = [self.pageCount integerValue] > 0 ? self.pageCount : @(20);
WeakSelf
self.footerConfigBlock = ^(NSInteger newCount) {
[weakSelf handleEndRefreshing:newCount];
};
self.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
footerRefreshBlock(weakSelf.footerConfigBlock);
}];
}
- (void)handleEndRefreshing:(NSInteger)count
{
if (self.mj_header.isRefreshing) {
[self.mj_header endRefreshing];
[self.mj_footer endRefreshing];
}
if (count < [self.pageCount integerValue]) {
[self.mj_footer endRefreshingWithNoMoreData];
}else{
[self.mj_footer endRefreshing];
}
}
#pragma mark --结束刷新-----
//若是外部想本身处理结束刷新,能够为tabelView添加的其它结束刷新的方法。
- (void)beginRefreshing
{
if (!self.mj_header) return;
[self.mj_header beginRefreshing];
}
- (void)endRefrehing
{
if (self.mj_header) {
[self.mj_header endRefreshing];
}
if (self.mj_footer) {
[self.mj_footer endRefreshing];
}
}
@end
复制代码
外部的调用以下:对象
- (void)configTableView
{
WeakSelf
[self.tableView normalHeaderRefreshingActionBlock:^(FooterConfigBlock _Nonnull footerConfig) {
weakSelf.page = 1;
//上拉刷新触发请求第一页数据。
[weakSelf requestData:^(NSInteger count) {
weakSelf.dataCount = count;
[weakSelf.tableView reloadData];
//请求成功后将数据的条数回调给tableView,让tableVie本身处理footer的设置
footerConfig(count);
} failCallBack:^{
[weakSelf.tableView endRefrehing];
}];
}];
[self.tableView backNormalFooterRefreshingActionBlock:^(FooterConfigBlock _Nonnull footerConfig) {
[weakSelf requestData:^(NSInteger count) {
weakSelf.dataCount += count;
[weakSelf.tableView reloadData];
//请求成功后将数据的条数回调给tableView,让tableVie本身处理footer的设置
footerConfig(count);
} failCallBack:^{
[weakSelf.tableView endRefrehing];
}];
}];
[self.tableView beginRefreshing];
}
- (void)requestData:(void(^)(NSInteger count))successCallBack failCallBack:(void(^)(void))failCallBack
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.page > 5) {
successCallBack(0);
}else{
successCallBack(20);
}
self.page += 1;
});
}
复制代码
以上只是本身的简单封装示例,MJRefresh提供了多种header和footer,能够根据业务或产品的要求自定义并封装适合本身的使用代码。继承
以上是本人的一些使用总结,若有错误,还请批评指正。谢谢!!!ci