MJTableViewController.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. // 代码地址: https://github.com/CoderMJLee/MJRefresh
  2. // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
  3. // MJTableViewController.m
  4. // MJRefreshExample
  5. //
  6. // Created by MJ Lee on 15/3/4.
  7. // Copyright (c) 2015年 itcast. All rights reserved.
  8. //
  9. #import "MJTableViewController.h"
  10. #import "MJRefresh.h"
  11. #import "UIView+MJExtension.h"
  12. #import "MJTestViewController.h"
  13. static const CGFloat MJDuration = 2.0;
  14. /**
  15. * 随机数据
  16. */
  17. #define MJRandomData [NSString stringWithFormat:@"随机数据---%d", arc4random_uniform(1000000)]
  18. @interface MJTableViewController()
  19. /** 用来显示的假数据 */
  20. @property (strong, nonatomic) NSMutableArray *data;
  21. @end
  22. @implementation MJTableViewController
  23. #pragma mark - 示例代码
  24. /**
  25. * UITableView + 下拉刷新 传统
  26. */
  27. - (void)example01
  28. {
  29. __weak typeof(self) weakSelf = self;
  30. // 添加传统的下拉刷新
  31. [self.tableView addLegendHeader];
  32. // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock)
  33. self.tableView.legendHeader.refreshingBlock = ^{
  34. [weakSelf loadNewData];
  35. };
  36. // 马上进入刷新状态
  37. [self.tableView.legendHeader beginRefreshing];
  38. /**
  39. 也可以这样使用
  40. self.tableView.header.refreshingBlock = ^{
  41. };
  42. [self.tableView.header beginRefreshing];
  43. 此时self.tableView.header == self.tableView.legendHeader
  44. */
  45. }
  46. /**
  47. * UITableView + 下拉刷新 动画图片
  48. */
  49. - (void)example02
  50. {
  51. // 添加动画图片的下拉刷新
  52. [self.tableView addGifHeader];
  53. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  54. [self.tableView.gifHeader setRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  55. // 设置普通状态的动画图片
  56. NSMutableArray *idleImages = [NSMutableArray array];
  57. for (NSUInteger i = 1; i<=60; i++) {
  58. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]];
  59. [idleImages addObject:image];
  60. }
  61. [self.tableView.gifHeader setImages:idleImages forState:MJRefreshHeaderStateIdle];
  62. // 设置即将刷新状态的动画图片(一松开就会刷新的状态)
  63. NSMutableArray *refreshingImages = [NSMutableArray array];
  64. for (NSUInteger i = 1; i<=3; i++) {
  65. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]];
  66. [refreshingImages addObject:image];
  67. }
  68. [self.tableView.gifHeader setImages:refreshingImages forState:MJRefreshHeaderStatePulling];
  69. // 设置正在刷新状态的动画图片
  70. [self.tableView.gifHeader setImages:refreshingImages forState:MJRefreshHeaderStateRefreshing];
  71. // 在这个例子中,即将刷新 和 正在刷新 用的是一样的动画图片
  72. // 马上进入刷新状态
  73. [self.tableView.gifHeader beginRefreshing];
  74. // 此时self.tableView.header == self.tableView.gifHeader
  75. }
  76. /**
  77. * UITableView + 下拉刷新 隐藏时间
  78. */
  79. - (void)example03
  80. {
  81. // 添加传统的下拉刷新
  82. [self.tableView addLegendHeader];
  83. // 隐藏时间
  84. self.tableView.header.updatedTimeHidden = YES;
  85. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  86. [self.tableView.header setRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  87. // 马上进入刷新状态
  88. [self.tableView.header beginRefreshing];
  89. // 此时self.tableView.header == self.tableView.legendHeader
  90. }
  91. /**
  92. * UITableView + 下拉刷新 隐藏状态和时间01
  93. */
  94. - (void)example04
  95. {
  96. // 添加动画图片的下拉刷新
  97. [self.tableView addGifHeader];
  98. // 隐藏时间
  99. self.tableView.header.updatedTimeHidden = YES;
  100. // 隐藏状态
  101. self.tableView.header.stateHidden = YES;
  102. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  103. [self.tableView.header setRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  104. // 设置普通状态的动画图片
  105. NSMutableArray *idleImages = [NSMutableArray array];
  106. for (NSUInteger i = 0; i<=72; i++) {
  107. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"PullToRefresh_%03zd", i]];
  108. [idleImages addObject:image];
  109. }
  110. [self.tableView.gifHeader setImages:idleImages forState:MJRefreshHeaderStateIdle];
  111. // 设置正在刷新状态的动画图片
  112. NSMutableArray *refreshingImages = [NSMutableArray array];
  113. for (NSUInteger i = 73; i<=140; i++) {
  114. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"PullToRefresh_%03zd", i]];
  115. [refreshingImages addObject:image];
  116. }
  117. [self.tableView.gifHeader setImages:refreshingImages forState:MJRefreshHeaderStateRefreshing];
  118. // 在这个例子中,即将刷新时没有动画图片
  119. // 马上进入刷新状态
  120. [self.tableView.header beginRefreshing];
  121. // 此时self.tableView.header == self.tableView.gifHeader
  122. // 由于动画图片是黑色的,所以故意设置tableView底色为黑色
  123. self.tableView.backgroundColor = [UIColor blackColor];
  124. }
  125. /**
  126. * UITableView + 下拉刷新 隐藏状态和时间02
  127. */
  128. - (void)example05
  129. {
  130. // 添加动画图片的下拉刷新
  131. [self.tableView addGifHeader];
  132. // 隐藏时间
  133. self.tableView.header.updatedTimeHidden = YES;
  134. // 隐藏状态
  135. self.tableView.header.stateHidden = YES;
  136. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  137. [self.tableView.header setRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  138. // 设置普通状态的动画图片
  139. NSMutableArray *idleImages = [NSMutableArray array];
  140. for (NSUInteger i = 1; i<=60; i++) {
  141. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]];
  142. [idleImages addObject:image];
  143. }
  144. [self.tableView.gifHeader setImages:idleImages forState:MJRefreshHeaderStateIdle];
  145. // 设置正在刷新状态的动画图片
  146. NSMutableArray *refreshingImages = [NSMutableArray array];
  147. for (NSUInteger i = 1; i<=3; i++) {
  148. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]];
  149. [refreshingImages addObject:image];
  150. }
  151. [self.tableView.gifHeader setImages:refreshingImages forState:MJRefreshHeaderStateRefreshing];
  152. // 马上进入刷新状态
  153. [self.tableView.header beginRefreshing];
  154. // 此时self.tableView.header == self.tableView.gifHeader
  155. }
  156. /**
  157. * UITableView + 下拉刷新 自定义文字
  158. */
  159. - (void)example06
  160. {
  161. // 添加传统的下拉刷新
  162. [self.tableView addLegendHeader];
  163. // 设置文字
  164. [self.tableView.header setTitle:@"下拉can刷新噻" forState:MJRefreshHeaderStateIdle];
  165. [self.tableView.header setTitle:@"一放手马上刷新咯" forState:MJRefreshHeaderStatePulling];
  166. [self.tableView.header setTitle:@"MJ哥正在帮你刷新..." forState:MJRefreshHeaderStateRefreshing];
  167. // 设置字体
  168. self.tableView.header.font = [UIFont systemFontOfSize:15];
  169. // 设置颜色
  170. self.tableView.header.textColor = [UIColor redColor];
  171. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  172. [self.tableView.header setRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  173. // 马上进入刷新状态
  174. [self.tableView.header beginRefreshing];
  175. // 此时self.tableView.header == self.tableView.legendHeader
  176. }
  177. /**
  178. * UITableView + 上拉刷新 传统
  179. */
  180. - (void)example11
  181. {
  182. __weak typeof(self) weakSelf = self;
  183. // 添加传统的上拉刷新
  184. [self.tableView addLegendFooter];
  185. // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock)
  186. self.tableView.legendFooter.refreshingBlock = ^{
  187. [weakSelf loadMoreData];
  188. };
  189. /**
  190. 也可以这样使用
  191. self.tableView.footer.refreshingBlock = ^{
  192. };
  193. 此时self.tableView.footer == self.tableView.legendFooter
  194. */
  195. }
  196. /**
  197. * UITableView + 上拉刷新 动画图片
  198. */
  199. - (void)example12
  200. {
  201. // 添加动画图片的上拉刷新
  202. [self.tableView addGifFooter];
  203. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  204. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  205. // 设置正在刷新状态的动画图片
  206. NSMutableArray *refreshingImages = [NSMutableArray array];
  207. for (NSUInteger i = 1; i<=3; i++) {
  208. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]];
  209. [refreshingImages addObject:image];
  210. }
  211. self.tableView.gifFooter.refreshingImages = refreshingImages;
  212. // 此时self.tableView.footer == self.tableView.gifFooter
  213. }
  214. /**
  215. * UITableView + 上拉刷新 隐藏状态01
  216. */
  217. - (void)example13
  218. {
  219. // 添加动画图片的上拉刷新
  220. [self.tableView addGifFooter];
  221. // 当上拉刷新控件出现50%时(出现一半),就会自动刷新。这个值默认是1.0(也就是上拉刷新100%出现时,才会自动刷新)
  222. // self.tableView.footer.appearencePercentTriggerAutoRefresh = 0.5;
  223. // 隐藏状态
  224. self.tableView.footer.stateHidden = YES;
  225. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  226. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  227. // 设置正在刷新状态的动画图片
  228. NSMutableArray *refreshingImages = [NSMutableArray array];
  229. for (NSUInteger i = 73; i<=140; i++) {
  230. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"PullToRefresh_%03zd", i]];
  231. [refreshingImages addObject:image];
  232. }
  233. self.tableView.gifFooter.refreshingImages = refreshingImages;
  234. // 此时self.tableView.footer == self.tableView.gifFooter
  235. // 由于动画图片是黑色的,所以故意设置tableView底色为黑色
  236. self.tableView.backgroundColor = [UIColor blackColor];
  237. }
  238. /**
  239. * UITableView + 上拉刷新 隐藏状态02
  240. */
  241. - (void)example14
  242. {
  243. // 添加动画图片的上拉刷新
  244. [self.tableView addGifFooter];
  245. // 隐藏状态
  246. self.tableView.footer.stateHidden = YES;
  247. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  248. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  249. // 设置正在刷新状态的动画图片
  250. NSMutableArray *refreshingImages = [NSMutableArray array];
  251. for (NSUInteger i = 1; i<=3; i++) {
  252. UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]];
  253. [refreshingImages addObject:image];
  254. }
  255. self.tableView.gifFooter.refreshingImages = refreshingImages;
  256. // 此时self.tableView.footer == self.tableView.gifFooter
  257. }
  258. /**
  259. * UITableView + 上拉刷新 全部加载完毕
  260. */
  261. - (void)example15
  262. {
  263. // 添加传统的上拉刷新
  264. [self.tableView addLegendFooter];
  265. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadLastData方法)
  266. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadLastData)];
  267. // 此时self.tableView.footer == self.tableView.legendFooter
  268. // 其他
  269. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"恢复数据加载" style:UIBarButtonItemStyleDone target:self action:@selector(recover)];
  270. }
  271. - (void)recover
  272. {
  273. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  274. // [self.tableView.footer beginRefreshing];
  275. self.tableView.footer.state = MJRefreshFooterStateIdle;
  276. // 此时self.tableView.footer == self.tableView.legendFooter
  277. }
  278. /**
  279. * UITableView + 上拉刷新 禁止自动加载
  280. */
  281. - (void)example16
  282. {
  283. // 添加传统的上拉刷新
  284. [self.tableView addLegendFooter];
  285. // 禁止自动加载
  286. self.tableView.footer.automaticallyRefresh = NO;
  287. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  288. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  289. // 此时self.tableView.footer == self.tableView.legendFooter
  290. }
  291. /**
  292. * UITableView + 上拉刷新 自定义文字
  293. */
  294. - (void)example17
  295. {
  296. // 添加传统的上拉刷新
  297. [self.tableView addLegendFooter];
  298. // 设置文字
  299. [self.tableView.footer setTitle:@"轻点或者轻拽可加载更多" forState:MJRefreshFooterStateIdle];
  300. [self.tableView.footer setTitle:@"MJ哥正在帮你加载..." forState:MJRefreshFooterStateRefreshing];
  301. [self.tableView.footer setTitle:@"没有再多的数据了" forState:MJRefreshFooterStateNoMoreData];
  302. // 设置字体
  303. self.tableView.footer.font = [UIFont systemFontOfSize:17];
  304. // 设置颜色
  305. self.tableView.footer.textColor = [UIColor blueColor];
  306. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  307. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  308. // 此时self.tableView.footer == self.tableView.legendFooter
  309. }
  310. /**
  311. * UITableView + 上拉刷新 加载后隐藏
  312. */
  313. - (void)example18
  314. {
  315. // 添加传统的上拉刷新
  316. [self.tableView addLegendFooter];
  317. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadOnceData方法)
  318. [self.tableView.footer setRefreshingTarget:self refreshingAction:@selector(loadOnceData)];
  319. // 此时self.tableView.footer == self.tableView.legendFooter
  320. }
  321. #pragma mark - 数据处理相关
  322. /**
  323. * 下拉刷新数据
  324. */
  325. - (void)loadNewData
  326. {
  327. // 1.添加假数据
  328. for (int i = 0; i<5; i++) {
  329. [self.data insertObject:MJRandomData atIndex:0];
  330. }
  331. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  332. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  333. // 刷新表格
  334. [self.tableView reloadData];
  335. // 拿到当前的下拉刷新控件,结束刷新状态
  336. [self.tableView.header endRefreshing];
  337. });
  338. }
  339. /**
  340. * 上拉加载更多数据
  341. */
  342. - (void)loadMoreData
  343. {
  344. // 1.添加假数据
  345. for (int i = 0; i<5; i++) {
  346. [self.data addObject:MJRandomData];
  347. }
  348. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  349. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  350. // 刷新表格
  351. [self.tableView reloadData];
  352. // 拿到当前的上拉刷新控件,结束刷新状态
  353. [self.tableView.footer endRefreshing];
  354. });
  355. }
  356. /**
  357. * 加载最后一份数据
  358. */
  359. - (void)loadLastData
  360. {
  361. // 1.添加假数据
  362. for (int i = 0; i<5; i++) {
  363. [self.data addObject:MJRandomData];
  364. }
  365. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  366. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  367. // 刷新表格
  368. [self.tableView reloadData];
  369. // 拿到当前的上拉刷新控件,变为没有更多数据的状态
  370. [self.tableView.footer noticeNoMoreData];
  371. });
  372. }
  373. /**
  374. * 只加载一次数据
  375. */
  376. - (void)loadOnceData
  377. {
  378. // 1.添加假数据
  379. for (int i = 0; i<25; i++) {
  380. [self.data addObject:MJRandomData];
  381. }
  382. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  383. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  384. // 刷新表格
  385. [self.tableView reloadData];
  386. // 隐藏当前的上拉刷新控件
  387. self.tableView.footer.hidden = YES;
  388. });
  389. }
  390. - (NSMutableArray *)data
  391. {
  392. if (!_data) {
  393. self.data = [NSMutableArray array];
  394. }
  395. return _data;
  396. }
  397. #pragma mark - 其他
  398. - (void)viewDidLoad
  399. {
  400. [super viewDidLoad];
  401. self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  402. [self performSelector:NSSelectorFromString(self.method) withObject:nil];
  403. }
  404. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  405. {
  406. return self.data.count;
  407. }
  408. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  409. {
  410. static NSString *ID = @"cell";
  411. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  412. if (cell == nil) {
  413. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
  414. }
  415. cell.textLabel.text = self.data[indexPath.row];;
  416. return cell;
  417. }
  418. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  419. {
  420. MJTestViewController *test = [[MJTestViewController alloc] init];
  421. if (indexPath.row % 2) {
  422. [self.navigationController pushViewController:test animated:YES];
  423. } else {
  424. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test];
  425. [self presentViewController:nav animated:YES completion:nil];
  426. }
  427. }
  428. - (void)dealloc
  429. {
  430. MJLog(@"%@销毁了", [self class]);
  431. }
  432. @end