这篇文章说下:MJRefresh和  EGOTableViewPullRefresh 的使用方法最下面有原理说明,若有不对或者建议请评论指出,先谢谢了:

首先是英文原文和类库下载地址:https://github.com/emreberge/EGOTableViewPullRefresh

然后创建好自己使用的tableview控件接着:

  • 添加 QuartzCore.framework 到你的工程中。
  • 将 EGOTableViewPullRefresh 拖到你的工程目录下。
     

然后在需要使用的类里写上

下拉是一个刷新的工作,所以需要我们添加的代码无非就是数据刷新的代码。

(1)在.h文件中添加如下代码

[plain]  view plain copy
  1. @interface ...ViewController : UITableViewController<EGORefreshTableHeaderDelegate>
  2. {
  3. EGORefreshTableHeaderView *refreshTableHeaderView;
  4. BOOL reloading;
  5. }
  6. - (void)reloadTableViewDataSource;
  7. - (void)doneLoadingTableViewData;

(2)在- (void)viewDidLoad函数中添加下面的代码。

[plain]  view plain copy
  1. if (refreshTableHeaderView == nil) {
  2. <span style="white-space:pre">  </span>EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
  3. view.delegate = self;
  4. [self.tableView addSubview:view];
  5. refreshTableHeaderView = view;
  6. [view release];
  7. }
  8. //最后一次更新的时间
  9. [refreshTableHeaderView refreshLastUpdatedDate];

(3)在对应的.m文件中添加如下方法

[plain]  view plain copy
  1. #pragma mark -
  2. #pragma mark Data Source Loading / Reloading Methods
  3. //更新列表数据
  4. - (void)reloadTableViewDataSource{
  5. [NSThread detachNewThreadSelector:@selector(updateNewsByPullTable) toTarget:self withObject:nil]; //异步加载数据,不影tableView动作
  6. reloading = YES;
  7. }
  8. //调用JSON服务获取数据
  9. - (void)updateNewsByPullTable
  10. {
  11. NSString *str = @"http://....../getAllNews.aspx";
  12. NSURL *url = [NSURL URLWithString:str];
  13. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  14. [request startSynchronous];
  15. //接收返回数据
  16. NSString *response = [request responseString];
  17. NSLog(@"%@",response);
  18. self.data = [response JSONValue];
  19. [self.tableView reloadData];
  20. }
  21. - (void)doneLoadingTableViewData{
  22. //model should call this when its done loading
  23. reloading = NO;
  24. [refreshTableHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
  25. }
  26. #pragma mark -
  27. #pragma mark UIScrollViewDelegate Methods
  28. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
  29. [refreshTableHeaderView egoRefreshScrollViewDidScroll:scrollView];
  30. }
  31. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
  32. [refreshTableHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
  33. }
  34. #pragma mark -
  35. #pragma mark EGORefreshTableHeaderDelegate Methods
  36. - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
  37. [self reloadTableViewDataSource];
  38. [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
  39. }
  40. - (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
  41. return reloading; // should return if data source model is reloading
  42. }
  43. - (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
  44. return [NSDate date]; // should return date data source was last changed
  45. }

4、总结

总的来说,实现这一功能并不复杂,关键在于-(void)reloadTableViewDataSource这一方法。这里我试了一下,读取数据的操作必须是异步的,要不然和tableView下拉再上弹这个动作会有很明显的延迟。再一次感受到了开源类库的强大,感谢这些大神们的无私贡献,让我们这些iOS开发初学者有机会能做出漂亮的应用。

也可以设置一个基类然后其他uitableview继承它:

.h

static NSString *CELL_ID = @"cell_id";

@class BaseTableView;

@protocol BaseTableViewDelegate <NSObject>

@optional

//下拉事件

- (void)pullDown:(BaseTableView *)tableView;

//上拉事件

- (void)pullUp:(BaseTableView *)tableView;

//选中单元格事件

- (void)didSelectRowAtIndexPath:(BaseTableView *)tabelView indexPath:(NSIndexPath *)indexPath;

@end

typedefvoid(^PullDonwFinish)(void);

typedefvoid(^PullUpFinish)(void);

@interface BaseTableView :UITableView<EGORefreshTableHeaderDelegate,UITableViewDataSource, UITableViewDelegate>

{

EGORefreshTableHeaderView *_refreshHeaderView;

BOOL _reloading;

UIButton *_moreButton;

}

@property(nonatomic,retain) NSMutableArray *data;

//是否显示下拉控件

@property(nonatomic,assign)BOOL refreshHeader;

//是否有更多(下一页)

@property(nonatomic,assign)BOOL isMore;

@property(nonatomic,copy)PullDonwFinish finishBlock;

@property(nonatomic,copy)PullUpFinish pullUpBlock;

//上拉代理对象

@property(nonatomic,assign)id<BaseTableViewDelegate> refreshDelegate;

//自动执行下拉动作

-(void)launchRefreshing;

- (void)reloadTableViewDataSource;

- (void)doneLoadingTableViewData;

@end

#import "BaseTableView.h
@implementation BaseTableView

- (id)initWithFrame:(CGRect)frame

{

self = [superinitWithFrame:frame];

if (self) {

// Initialization code

[self_initViews];

}

return self;

}

- (void)awakeFromNib {

[superawakeFromNib];

[self_initViews];

}

- (void)_initViews {

self.backgroundColor =RGB(242, 243, 240);

self.refreshHeader =YES;

self.isMore =YES;

self.delegate =self;

self.dataSource =self;

_moreButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

_moreButton.frame =CGRectMake(0,0, self.width,44);

_moreButton.backgroundColor = [UIColorclearColor];

[_moreButtonsetTitle:@""forState:UIControlStateNormal];

_moreButton.titleLabel.font = [UIFontsystemFontOfSize:12.0f];

[_moreButtonsetTitleColor:[UIColorlightGrayColor] forState:UIControlStateNormal];

[_moreButtonaddTarget:selfaction:@selector(loadMoreAction)forControlEvents:UIControlEventTouchUpInside];

UIActivityIndicatorView *activityView = [[UIActivityIndicatorViewalloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

activityView.frame =CGRectMake(90,10, 20, 20);

[activityViewstopAnimating];

activityView.tag =2013;

[_moreButtonaddSubview:activityView];

self.tableFooterView =_moreButton;

}

-(void)launchRefreshing

{

if (_reloading) {

_reloading = NO;

[UIViewanimateWithDuration:0.4animations:^{

[selfsetContentOffset:CGPointMake(0, -80)];

}completion:^(BOOL finished) {

if (finished) {

//设置停止拖拽

[_refreshHeaderViewperformSelector:@selector(egoRefreshScrollViewDidEndDragging:)withObject:selfafterDelay:0.2];

}

}];

}else{

//下拉之前还原_refreshHeaderView的state

[_refreshHeaderViewsetState:EGOOPullRefreshNormal];

[UIViewanimateWithDuration:0.4animations:^{

[selfsetContentOffset:CGPointMake(0, -80)];

}completion:^(BOOL finished) {

if (finished) {

[_refreshHeaderViewsetState:EGOOPullRefreshPulling];

//设置停止拖拽

[_refreshHeaderViewperformSelector:@selector(egoRefreshScrollViewDidEndDragging:)withObject:selfafterDelay:0.2];

}

}];

}

}

- (void)setRefreshHeader:(BOOL)refreshHeader {

_refreshHeader = refreshHeader;

if (self.refreshHeader) {

if (_refreshHeaderView ==nil) {

//创建下拉控件

_refreshHeaderView = [[EGORefreshTableHeaderViewalloc] initWithFrame:CGRectMake(0.0f,0.0f - self.bounds.size.height,self.frame.size.width,self.bounds.size.height)];

_refreshHeaderView.delegate =self;

_refreshHeaderView.backgroundColor = [UIColorclearColor];

[_refreshHeaderViewrefreshLastUpdatedDate];

}

[selfaddSubview:_refreshHeaderView];

}else {

if (_refreshHeaderView.superview !=nil) {

[_refreshHeaderViewremoveFromSuperview];

}

}

}

//上拉按钮的点击事件

- (void)loadMoreAction {

if (self.pullUpBlock !=nil) {

self.pullUpBlock();

}

//调用代理对象的协议方法

if ([self.refreshDelegaterespondsToSelector:@selector(pullUp:)]) {

[self.refreshDelegatepullUp:self];

}

[_moreButtonsetTitle:@"正在加载..."forState:UIControlStateNormal];

UIActivityIndicatorView *activityView = (UIActivityIndicatorView *)[_moreButtonviewWithTag:2013];

[activityViewstartAnimating];

}

- (void)setIsMore:(BOOL)isMore {

_isMore = isMore;

if (self.isMore) {

[_moreButtonsetTitle:@"加载更多数据"forState:UIControlStateNormal];

_moreButton.enabled =YES;

}else {

[_moreButtonsetTitle:@"没有更多数据"forState:UIControlStateNormal];

_moreButton.enabled =NO;

}

UIActivityIndicatorView *activityView = (UIActivityIndicatorView *)[_moreButtonviewWithTag:2013];

[activityViewstopAnimating];

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

[tableView deselectRowAtIndexPath:indexPathanimated:YES];

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return self.data.count;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:CELL_ID];

if (!cell) {

cell = [[UITableViewCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CELL_ID];

}

return cell;

}

/*________________________下拉控件相关方法________________________________*/

#pragma mark -

#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{

_reloading = YES;

}

//收起下拉刷新

- (void)doneLoadingTableViewData{

_reloading = NO;

[_refreshHeaderViewegoRefreshScrollViewDataSourceDidFinishedLoading:self];

}

#pragma mark -

#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

[_refreshHeaderViewegoRefreshScrollViewDidScroll:scrollView];

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

[_refreshHeaderViewegoRefreshScrollViewDidEndDragging:scrollView];

//偏移量.y + tableView.height =内容的高度

//h是上拉超出来的尺寸

float h = scrollView.contentOffset.y + scrollView.height - scrollView.contentSize.height;

if (h > 30 &&self.isMore) {

[selfloadMoreAction];

}

}

#pragma mark -

#pragma mark EGORefreshTableHeaderDelegate Methods

//下拉到一定距离,手指放开时调用

- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{

[selfreloadTableViewDataSource];

//停止加载,弹回下拉

// [self performSelector:@selector(doneLoadingTableViewData)

//               withObject:nil afterDelay:3.0];

if (self.finishBlock !=nil) {

self.finishBlock();

}

if ([self.refreshDelegaterespondsToSelector:@selector(pullDown:)]) {

[self.refreshDelegatepullDown:self];

}

}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{

return_reloading;// should return if data source model is reloading

}

//取得下拉刷新的时间

- (NSDate *)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{

return [NSDatedate]; // should return date data source was last changed

}

@end

浅谈下拉刷新和上拉加载更多原理:

下文出自:  http://blog.csdn.net/hmt20130412/article/details/32695305

很多App中,新闻或者展示类都存在下拉刷新和上拉加载的效果,网上提供了实现这种效果的第三方类(详情请见MJRefresh和  EGOTableViewPullRefresh ),用起来很方便,但是闲暇之余,我们可以思考下,这种效果实现的原理是什么,我以前说过,只要是动画都是骗人的,只要不是硬件问题大部分效果都能在系统UI的基础上做出来.

@下面是关键代码分析:

// 下拉刷新的原理
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{if (scrollView.contentOffset.y < - 100) {

  [UIView animateWithDuration:1.0 animations:^{

      //  frame发生偏移,距离顶部150的距离(可自行设定)
      self.tableView.contentInset = UIEdgeInsetsMake(150.0f, 0.0f, 0.0f, 0.0f);
  } completion:^(BOOL finished) {

      /**
       *  发起网络请求,请求刷新数据
       */  }];}
}// 上拉加载的原理
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{NSLog(@"%f",scrollView.contentOffset.y);NSLog(@"%f",scrollView.frame.size.height);NSLog(@"%f",scrollView.contentSize.height);/***  关键-->*  scrollView一开始并不存在偏移量,但是会设定contentSize的大小,所以contentSize.height永远都会比contentOffset.y高一个手机屏幕的*  高度;上拉加载的效果就是每次滑动到底部时,再往上拉的时候请求更多,那个时候产生的偏移量,就能让contentOffset.y + 手机屏幕尺寸高大于这*  个滚动视图的contentSize.height*/if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height) {

  NSLog(@"%d %s",__LINE__,__FUNCTION__);
  [UIView commitAnimations];

  [UIView animateWithDuration:1.0 animations:^{
      //  frame发生的偏移量,距离底部往上提高60(可自行设定)
      self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 60, 0);
  } completion:^(BOOL finished) {

      /**
       *  发起网络请求,请求加载更多数据
       *  然后在数据请求回来的时候,将contentInset改为(0,0,0,0)
       */
  }];}
}

iOS UITableView下拉刷新上拉加载更多EGOTableViewPullRefresh类库使用初级剑侠篇(欢迎提建议和分享遇到的问题)相关推荐

  1. uni-app下拉刷新触底加载更多

    首先在pages.json 配置文件中配置    "enablePullDownRefresh": true  需要在哪用加载就配置在路由的style里 两个事件 //下拉刷新 o ...

  2. recyclerview的数据刷新(下拉刷新和自动加载更多)以及添加提示语(例如:“数据已加载完毕”)

    下拉加载更多的核心是SwipeRefreshLayout搭配Recyclerview进行使用.布局为 <android.support.v4.widget.SwipeRefreshLayout ...

  3. Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表

    本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...

  4. Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout

    下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...

  5. Flutter开发之ListView下拉刷新上拉加载更多(35)

    在Flutter开发之ListView组件(21) 文章中,我们了解了ListView组件的基本使用.但是数据比较少,没有涉及分页加载.而实际开发中,下拉刷新和分页加载几乎是所有APP的标配.在iOS ...

  6. 分享轮子-flutter下拉刷新上拉加载

    flutter下拉上拉组件轮子 什么是flutter? 首先说下flutter,估计这个应该挺多人没听过flutter这个框架,它是一个google推出的跨平台的移动应用UI框架,和React Nat ...

  7. android 列表上拉加载更多,Android 下拉刷新,上拉加载更多控件–支持ListView,GridView和ScrollView...

    麦洛遇到这样一个需求,实现类似于IOS下拉刷新,上拉加载更多的控件.麦洛google,baidu了一番,网上有不少实现,比较常见的是国外牛人的实现,不过国外的实现基本上都是扩展于ListView,所以 ...

  8. jquery手机端页面下拉刷新,上划加载更多

    手机页面下拉刷新,上划加载更多,IOS不能下拉的问题解决 -转圈的是需要引用样式,代码删除了 上划加载时的样子 <script type="text/javascript"& ...

  9. 下拉加载 实现 java_[Java教程]iscroll5实现一个下拉刷新上拉加载的效果

    [Java教程]iscroll5实现一个下拉刷新上拉加载的效果 0 2016-08-24 15:00:08 直接上代码!!! * { margin: 0; padding: 0; } ul, li { ...

最新文章

  1. 异步通知是什么意思_一次相亲经历,我彻底搞懂了阻塞非阻塞、同步异步
  2. asyncdata 获取参数_载入页面初始数据(asyncData)《 Nuxt.js:异步数据 》
  3. mysql 字段授权_mysql授权管理
  4. hive窗口函数分组排序并取第一个值_Hive(七)Hive分析窗口函数
  5. OpenCASCADE:使用扩展数据交换 XDE之几何尺寸和公差 (GDT)
  6. HubbleDotNet使用备忘
  7. 微软今天发布免费安全软件套装
  8. e2e_cli遇坑记录
  9. java并发编程(13)-- 线程 死锁和定位
  10. 关于nagios 邮件报警问题
  11. java反编译 jd-gui_JD-GUI(Java反编译工具)
  12. Fiddler 5.0 中文版
  13. Https 证书相关
  14. php 背单词系统_网上背单词程序PHP
  15. TF卡和SD卡的区别
  16. java阴阳师抽卡算法_阴阳师抽卡小技巧,抽出SSR很轻松
  17. elasticjob已下线_elasticJob 源码解析之自诊断恢复
  18. SDUTOJ打字训练
  19. teamlab什么意思_去看炸火的teamLab大型个展前 你应该知道的事
  20. 澳门W.B.C开启世界区块链“峰会+嘉年华+学院+全球行”新模式

热门文章

  1. MCDF SV lab3 介绍与总结
  2. getnameinfo函数
  3. 通俗易懂的主成分分析法(PCA)详解
  4. 手机C语言代码,C语言(示例代码)
  5. raptor流程图赋值语句_raptor流程图编程
  6. ecstore mysql_详解Ecstore中的数据表结构定义文件dbschema
  7. xml中的sql 标签中应使用 尖括号,感叹号 注释. 其他方式会被当成sql语句执行.
  8. GBase 8a 数据导入导出
  9. 只有一种人不会成为直销难民
  10. WordPress微信壁纸小程序源码 高清壁纸下载小程序