iOS笔记-(利用EGORefreshTableHeaderView自定义上拉加载和下拉刷新)

本文介绍如何在iOS应用中使用EGORefreshTableHeader实现下拉刷新与上拉加载功能,包括创建工程、添加代理方法、设置下拉与上拉效果以及数据加载逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

</pre><p class="p1"></p><pre name="code" class="objc">GIthub下载一个DEMO,在RootviewController中查看.
UIScrollViewDelegate:是监听滑动的距离
EGORefreshTableHeaderDelegate:是头部控件的代理方法.

//1.下拉到一定距离,手指放开会触发:
(void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
}
//2.数据加载完毕后,停止加载,视图弹回原来位置,
- (void)doneLoadingTableViewData{
}

// 亲手示范,创建工程
//1.
创建一个基本的BaseTableview,带有下拉刷新功能.
BaseTableview继承UITableView.
//2.
导入EGOTablePullRefresh文件夹到工程中.
#import  “EGORefreshTableHeaderView.h"
//3. 私有变量
EGORefreshTableHeaderView *_refreshHeaderView;//头部控件

//4.不是所有的TableView都要下拉刷新功能,此时添加
@property (nonatomic,assign) BOOL refreshHeader;//是否需要下拉效果

//5.在这里添加头部控件
//5-1
/*方法一
 *用XIB创建
*/
- (void)awakeFromNib{
    [self initHeaderView];
}
/* 方法二
 * 用代码创建
*/
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
    self = [super initWithFrame:frame style:style];
    if (self) {
        [self initHeaderView];
    }
    return self;
}

//5-2
//打开下拉效果
    self.refreshHeader = YES;
//重写下拉布尔型值
- (void)setRefreshHeader:(BOOL)refreshHeader{
    _refreshHeader = refreshHeader;
    if (_refreshHeader) {
        //打开下拉效果,添加头部控件
        [self addSubview:_refreshHeaderView];
    }else{
        //关闭下拉效果,移除头部控件
        if ([_refreshHeaderView superview]) {
            [_refreshHeaderView removeFromSuperview];
        }
    }
}

//6.添加EGO代理方法..
#pragma mark -
#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{
    _reloading = YES;
    
}

- (void)doneLoadingTableViewData{
    _reloading = NO;
    [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self];
    
}


#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    [_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
}


#pragma mark -
#pragma mark EGORefreshTableHeaderDelegate Methods

- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
    [self reloadTableViewDataSource];
    [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
    
}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
    return _reloading;
}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
    return [NSDate date];
}

//下拉,当手指放开时候,调用egoRefreshTableHeaderDidTriggerRefresh方法,此时
BaseTableView和控制器要进行通讯,BaseTableView通知控制器此时请求网络数据.(把自己self,路径indexPath传出去)
通讯方式用:通知,Block,Delegate.
在这我用Delegate.delegate方法并不一定会实现
所有判断一下.因为是可选的
 if([self.baseDelegate respondsToSelector:@selector(pullDownWithTableView:)]){
        [self.baseDelegate pullDownWithTableView:self];
    }
//注意:因为BaseTableView继承UITableView, 而且
BaseTableView遵守了UITableViewDelegate,UITableViewDataSource,所以在控制器中 不用遵守UITableViewDelegate,UITableViewDataSource.
在控制器中,当下拉加载完数据后,控制器做的事情是弹回原来位置.


//7.增加上拉控件
上拉控件可以放在taleView的尾部视图.


//BaseTableView有个数据源,数组data.先判断data是否有数据,无数据将尾部视图隐藏;然后再判断有数据时候,是否最后一页.是最后一页,”已加载全部数据”.

//点击尾部视图”查看更多”,加载数据时,尾部视图变位”正在加载”.当加载完毕,尾部视图变为原样”查看更多”.

//当加载到最后一页,尾部视图显示为:“已加载全部数据”

//在控制器中,调用BaseTableView的reloadData时,复写reloadData方法,让控制器尾部视图上拉加载完毕后停止风火轮的转动.

//除了点击”查看更多”按钮能实现上拉加载,还可以设置当手指停止拖拽的时候,判断scrollview的偏移量是否满足 上拉加载.
(1)float offset = scrollView.contentOffset.y;
(2)float contentHeight = scrollView.contentSize.height;
(3)//当滑动到尾部视图”查看更多”,差值就是scrollView的高度
    float sub = contentHeight - offset;
if(sub - scrollView.bounds.size.height > 30){

}
</pre><pre name="code" class="objc">以下是原代码,继承BaseTableView,可以做更多有趣的上下拉加载数据效果...
<pre name="code" class="objc">//
//  BaseTableView.h
//  DEMOForEGOTalbeViewPullRefresh
//
//  Created by kun on 15/8/1.
//  Copyright (c) 2015年 kun. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "EGORefreshTableHeaderView.h"
/**
 *  定制协议,BaseTableView通知控制器去请求数据
 */
@class BaseTableView;
@protocol BaseTableViewDelegate <NSObject>
@optional
- (void)pullDownWithTableView:(BaseTableView *)baseTableView;//下拉刷新
- (void)pullUpWithTableView:(BaseTableView *)baseTableView;  //上拉加载
- (void)baseTableView:(BaseTableView *)baseTableView didselectRowAtIndexPath:(NSIndexPath *)indexPath;//选中某一行
@end

@interface BaseTableView : UITableView<EGORefreshTableHeaderDelegate,UITableViewDelegate,UITableViewDataSource>{
    /**
     *  手动添加以下私有变量
     *  上拉控件
     */
    EGORefreshTableHeaderView *_refreshHeaderView;//头部控件
    BOOL _reloading;//是否正在加载
    
    /**
     *  下拉控件
     */
    UIButton *_btnPullUp;
    UIActivityIndicatorView *_acitivityView;
}
@property (nonatomic,assign) BOOL refreshHeader;//是否需要下拉效果
@property (nonatomic,strong) NSArray *data;//为tableView提供数据
@property (nonatomic,weak) id <BaseTableViewDelegate>baseDelegate;
/**
 *  上拉加载完全部数据的标记
 */
@property (nonatomic,assign) BOOL isPullUpAllFinish;
/**
 *  数据加载完毕后,停止加载,视图弹回原来位置
 */
- (void)doneLoadingTableViewData;
/**
 *  停止上拉加载
 */
- (void)stopPullUpLoadMore;
@end
</pre><pre name="code" class="objc">
</pre><pre name="code" class="objc">//
//  BaseTableView.m
//  DEMOForEGOTalbeViewPullRefresh
//
//  Created by kun on 15/8/1.
//  Copyright (c) 2015年 kun. All rights reserved.
//

#import "BaseTableView.h"

@implementation BaseTableView
/*方法一
 *用XIB创建
*/
- (void)awakeFromNib{
    //初始化下拉视图
    [self initHeaderView];
    //初始化尾部控件
    [self initFooterView];
}
/* 方法二
 * 用代码创建
*/
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
    self = [super initWithFrame:frame style:style];
    if (self) {
        //初始化下拉视图
        [self initHeaderView];
        //初始化尾部控件
        [self initFooterView];
    }
    return self;
}

#pragma mark - init
//初始化头部控件
- (void)initHeaderView{
    //1.设置头部控件
    _refreshHeaderView = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.bounds.size.height, self.frame.size.width, self.bounds.size.height)];
    _refreshHeaderView.delegate = self;
    _refreshHeaderView.backgroundColor = [UIColor clearColor];
    
    //2.打开下拉效果
    self.refreshHeader = YES;
    
    //3.添加tableView代理对象为BaseTableView
    self.dataSource = self;
    self.delegate   = self;
}

//初始化尾部控件
- (void)initFooterView{
    /**
     *  先创建"查看更多"按钮,当点击"查看更多"按钮,上拉数据,同时出现风火轮
     */
    //1.
    _btnPullUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    _btnPullUp.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44);
    _btnPullUp.backgroundColor = [UIColor clearColor];
    [_btnPullUp setTitle:@"查看更多" forState:UIControlStateNormal];
    [_btnPullUp addTarget:self action:@selector(pullUpToLoadMore) forControlEvents:UIControlEventTouchUpInside];
    self.tableFooterView = _btnPullUp;
    
    //2.风火轮设置
    UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    activityView.frame = CGRectMake(100, 10, 20, 20);
    [activityView stopAnimating];//初始化时停止旋转。
    [_btnPullUp addSubview:activityView];
    _acitivityView = activityView;
}

//重写下拉布尔型值
- (void)setRefreshHeader:(BOOL)refreshHeader{
    _refreshHeader = refreshHeader;
    if (_refreshHeader) {
        //打开下拉效果,添加头部控件
        [self addSubview:_refreshHeaderView];
    }else{
        //关闭下拉效果,移除头部控件
        if ([_refreshHeaderView superview]) {
            [_refreshHeaderView removeFromSuperview];
        }
    }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

#pragma mark - Action
//上拉加载更多
- (void)pullUpToLoadMore{
    //1.判断代理方法是否执行
    if ([self.baseDelegate respondsToSelector:@selector(pullUpWithTableView:)]) {
        //1-1
        [self.baseDelegate pullUpWithTableView:self];
        //1-2.尾部视图相应变化
        [self startPullUpLoadMore];
    }
    
}

#pragma mark - UITableViewDelegate
//(子类可以覆盖父类的代理方法)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([self.baseDelegate respondsToSelector:@selector(baseTableView:didselectRowAtIndexPath:)]) {
        [self.baseDelegate baseTableView:self didselectRowAtIndexPath:indexPath];
    }
}

- (void)reloadData{
    [super reloadData];
    //停止上拉加载更多
    [self stopPullUpLoadMore];
}

#pragma mark -
#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{
    _reloading = YES;
    
}
//2.数据加载完毕后,停止加载,视图弹回原来位置,
- (void)doneLoadingTableViewData{
    _reloading = NO;
    [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self];
}


#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
}

//当手指停止拖拽的时候调用.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    [_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
    
    //1.判断是否到最后一页
    if(!self.isPullUpAllFinish){
        return;
    }
    
    //2.
   float offset = scrollView.contentOffset.y;
   float contentHeight = scrollView.contentSize.height;
    //当滑动到尾部视图"查看更多",差值就是scrollView的高度
    float sub = contentHeight - offset;
    if(scrollView.bounds.size.height - sub> 30){
        //2-1.控制状态发生变化
        [self startPullUpLoadMore];
        //2-2.通知控制器,上拉加载更多
        if ([self.baseDelegate respondsToSelector:@selector(pullUpWithTableView:)]) {
            [self.baseDelegate pullUpWithTableView:self];
        }
    }
    
}


#pragma mark -
#pragma mark EGORefreshTableHeaderDelegate Methods
//1.下拉到一定距离,手指放开会触发:
- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
    //1.设置为正在加载状态
    [self reloadTableViewDataSource];
    
    //2.停止加载,弹回原来位置
    //2-1 调试用
//    [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
    //2-2 与控制器进行通讯
    if([self.baseDelegate respondsToSelector:@selector(pullDownWithTableView:)]){
        [self.baseDelegate pullDownWithTableView:self];
    }
}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
    return _reloading;
}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
    return [NSDate date];
}


#pragma mark - Private
/**
 *  开始上拉加载
 */
- (void)startPullUpLoadMore{

        //1.文字发生变化
        _btnPullUp.enabled = NO;
        [_btnPullUp setTitle:@"正在加载..." forState:UIControlStateNormal];
        //2.风火轮转动
        [_acitivityView startAnimating];
    
}

/**
 *  停止上拉加载
 */
- (void)stopPullUpLoadMore{
    //判断是否有数据
    if (self.data.count > 0) {
        //0.显示
        _btnPullUp.hidden = NO;
        //1.文字恢复原样
        _btnPullUp.enabled = YES;
        [_btnPullUp setTitle:@"查看更多" forState:UIControlStateNormal];
        //2.风火轮停止转动
        [_acitivityView stopAnimating];
        //3.判断是否最后一页
        if(!self.isPullUpAllFinish){
         [_btnPullUp setTitle:@"已加载全部数据" forState:UIControlStateNormal];
            _btnPullUp.enabled = NO;
        }
    }else{
        _btnPullUp.hidden = YES;
    }
}

@end

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值