MJRefresh的二次封裝

日常用的刷新用是開源的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

相關文章
相關標籤/搜索