MJRefresh的二次封装

栏目: IOS · 发布时间: 4年前

内容简介:平常用的刷新用是开源的MJ为以上只是示例,MJ中作者提供来多种不同UI和交互的header和footer供大家选择使用。

平常用的刷新用是开源的 MJRefresh ,这个刷新库想必也是很多开发者比较熟悉的一个库,作者采用继承的方式,不同的层次有不同的功能与UI展示,用起来简洁,方便。

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供大家选择使用。

平常这样直接按照作者的Demo示例用可以,但是个人总觉得不太好。就想着能够封装下(主要是懒,想省点事)。

先说下基本的需求:一个tableView的列表,每页请求20(注:不同的公司可能不同的每页条数,这里只是举例)条数据,下拉刷新的时候是重新请求第一页的数据,上拉加载更多的时候是请求下一页数据。如果下一页数据还是20条,则认为还有数据,将footr以正常的状态结束刷新。再次上拉加载的时候,还会正常请求下一页的数据。 如果加载出来的数据少于一页的数据条数(20条),那么就认为没有更多数据了,这时就将footer以没有更多数据的状态结束刷新,再进行上拉加载的时候,将不起作用。

我想要的效果是,我外部调用的时候,我只想知道触发去请求刷新和加载更多的时机, 其它的都不想管。

本人目前的实现是:给UITableView写了一个类别(UICollectionView同理。UIScrollView也可以进行下拉刷新,只不过是不用上拉加载更多了)。写了两个方法,分别是下拉刷新和上拉加载的调用。同时增加了两个关联对象:每页的数据条数和一个上拉加载更多后的footer的设置回调的block。 示例代码如下:

#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,可以根据业务或产品的要求自定义并封装适合自己的使用代码。

以上是本人的一些使用总结,如有错误,还请批评指正。谢谢!!!


以上所述就是小编给大家介绍的《MJRefresh的二次封装》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Nature of Code

The Nature of Code

Daniel Shiffman / The Nature of Code / 2012-12-13 / GBP 19.95

How can we capture the unpredictable evolutionary and emergent properties of nature in software? How can understanding the mathematical principles behind our physical world help us to create digital w......一起来看看 《The Nature of Code》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具