MJTableViewController.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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年 小码哥. All rights reserved.
  8. //
  9. #import "MJTableViewController.h"
  10. #import "UIView+MJExtension.h"
  11. #import "MJTestViewController.h"
  12. #import "UIViewController+Example.h"
  13. #import "MJRefresh.h"
  14. // 自定义的header
  15. #import "MJChiBaoZiHeader.h"
  16. #import "MJChiBaoZiFooter.h"
  17. #import "MJChiBaoZiFooter2.h"
  18. #import "MJDIYHeader.h"
  19. #import "MJDIYAutoFooter.h"
  20. #import "MJDIYBackFooter.h"
  21. static const CGFloat MJDuration = 2.0;
  22. /**
  23. * 随机数据
  24. */
  25. #define MJRandomData [NSString stringWithFormat:@"随机数据---%d", arc4random_uniform(1000000)]
  26. @interface MJTableViewController()
  27. /** 用来显示的假数据 */
  28. @property (strong, nonatomic) NSMutableArray *data;
  29. @end
  30. @implementation MJTableViewController
  31. #pragma mark - 示例代码
  32. #pragma mark UITableView + 下拉刷新 默认
  33. - (void)example01
  34. {
  35. __weak __typeof(self) weakSelf = self;
  36. // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock)
  37. self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
  38. [weakSelf loadNewData];
  39. }];
  40. // 马上进入刷新状态
  41. [self.tableView.mj_header beginRefreshing];
  42. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  43. [self.tableView.mj_header beginRefreshing];
  44. });
  45. }
  46. #pragma mark UITableView + 下拉刷新 动画图片
  47. - (void)example02
  48. {
  49. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  50. self.tableView.mj_header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  51. // 马上进入刷新状态
  52. [self.tableView.mj_header beginRefreshing];
  53. }
  54. #pragma mark UITableView + 下拉刷新 隐藏时间
  55. - (void)example03
  56. {
  57. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  58. MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  59. // 设置自动切换透明度(在导航栏下面自动隐藏)
  60. header.automaticallyChangeAlpha = YES;
  61. // 隐藏时间
  62. header.lastUpdatedTimeLabel.hidden = YES;
  63. // 马上进入刷新状态
  64. [header beginRefreshing];
  65. // 设置header
  66. self.tableView.mj_header = header;
  67. }
  68. #pragma mark UITableView + 下拉刷新 隐藏状态和时间
  69. - (void)example04
  70. {
  71. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  72. MJChiBaoZiHeader *header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  73. // 隐藏时间
  74. header.lastUpdatedTimeLabel.hidden = YES;
  75. // 隐藏状态
  76. header.stateLabel.hidden = YES;
  77. // 马上进入刷新状态
  78. [header beginRefreshing];
  79. // 设置header
  80. self.tableView.mj_header = header;
  81. }
  82. #pragma mark UITableView + 下拉刷新 自定义文字
  83. - (void)example05
  84. {
  85. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  86. MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  87. // 设置文字
  88. [header setTitle:@"Pull down to refresh" forState:MJRefreshStateIdle];
  89. [header setTitle:@"Release to refresh" forState:MJRefreshStatePulling];
  90. [header setTitle:@"Loading ..." forState:MJRefreshStateRefreshing];
  91. // 设置字体
  92. header.stateLabel.font = [UIFont systemFontOfSize:15];
  93. header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14];
  94. // 设置颜色
  95. header.stateLabel.textColor = [UIColor redColor];
  96. header.lastUpdatedTimeLabel.textColor = [UIColor blueColor];
  97. // 马上进入刷新状态
  98. [header beginRefreshing];
  99. // 设置刷新控件
  100. self.tableView.mj_header = header;
  101. }
  102. #pragma mark UITableView + 下拉刷新 自定义刷新控件
  103. - (void)example06
  104. {
  105. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
  106. self.tableView.mj_header = [MJDIYHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];
  107. [self.tableView.mj_header beginRefreshing];
  108. }
  109. #pragma mark UITableView + 上拉刷新 默认
  110. - (void)example11
  111. {
  112. [self example01];
  113. __weak __typeof(self) weakSelf = self;
  114. // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock)
  115. self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
  116. [weakSelf loadMoreData];
  117. }];
  118. }
  119. #pragma mark UITableView + 上拉刷新 动画图片
  120. - (void)example12
  121. {
  122. [self example01];
  123. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  124. self.tableView.mj_footer = [MJChiBaoZiFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  125. }
  126. #pragma mark UITableView + 上拉刷新 隐藏刷新状态的文字
  127. - (void)example13
  128. {
  129. [self example01];
  130. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  131. MJChiBaoZiFooter *footer = [MJChiBaoZiFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  132. // 当上拉刷新控件出现50%时(出现一半),就会自动刷新。这个值默认是1.0(也就是上拉刷新100%出现时,才会自动刷新)
  133. // footer.triggerAutomaticallyRefreshPercent = 0.5;
  134. // 隐藏刷新状态的文字
  135. footer.refreshingTitleHidden = YES;
  136. // 设置footer
  137. self.tableView.mj_footer = footer;
  138. }
  139. #pragma mark UITableView + 上拉刷新 全部加载完毕
  140. - (void)example14
  141. {
  142. [self example01];
  143. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadLastData方法)
  144. self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadLastData)];
  145. // 其他
  146. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"恢复数据加载" style:UIBarButtonItemStyleDone target:self action:@selector(reset)];
  147. }
  148. - (void)reset
  149. {
  150. [self.tableView.mj_footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  151. // [self.tableView.mj_footer beginRefreshing];
  152. [self.tableView.mj_footer resetNoMoreData];
  153. }
  154. #pragma mark UITableView + 上拉刷新 禁止自动加载
  155. - (void)example15
  156. {
  157. [self example01];
  158. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  159. MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  160. // 禁止自动加载
  161. footer.automaticallyRefresh = NO;
  162. // 设置footer
  163. self.tableView.mj_footer = footer;
  164. }
  165. #pragma mark UITableView + 上拉刷新 自定义文字
  166. - (void)example16
  167. {
  168. [self example01];
  169. // 添加默认的上拉刷新
  170. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  171. MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  172. // 设置文字
  173. [footer setTitle:@"Click or drag up to refresh" forState:MJRefreshStateIdle];
  174. [footer setTitle:@"Loading more ..." forState:MJRefreshStateRefreshing];
  175. [footer setTitle:@"No more data" forState:MJRefreshStateNoMoreData];
  176. // 设置字体
  177. footer.stateLabel.font = [UIFont systemFontOfSize:17];
  178. // 设置颜色
  179. footer.stateLabel.textColor = [UIColor blueColor];
  180. // 设置footer
  181. self.tableView.mj_footer = footer;
  182. }
  183. #pragma mark UITableView + 上拉刷新 加载后隐藏
  184. - (void)example17
  185. {
  186. [self example01];
  187. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadOnceData方法)
  188. self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadOnceData)];
  189. }
  190. #pragma mark UITableView + 上拉刷新 自动回弹的上拉01
  191. - (void)example18
  192. {
  193. [self example01];
  194. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  195. self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  196. // 设置了底部inset
  197. self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 30, 0);
  198. // 忽略掉底部inset
  199. self.tableView.mj_footer.ignoredScrollViewContentInsetBottom = 30;
  200. }
  201. #pragma mark UITableView + 上拉刷新 自动回弹的上拉02
  202. - (void)example19
  203. {
  204. [self example01];
  205. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadLastData方法)
  206. self.tableView.mj_footer = [MJChiBaoZiFooter2 footerWithRefreshingTarget:self refreshingAction:@selector(loadLastData)];
  207. self.tableView.mj_footer.automaticallyChangeAlpha = YES;
  208. }
  209. #pragma mark UITableView + 上拉刷新 自定义刷新控件(自动刷新)
  210. - (void)example20
  211. {
  212. [self example01];
  213. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  214. self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  215. }
  216. #pragma mark UITableView + 上拉刷新 自定义刷新控件(自动回弹)
  217. - (void)example21
  218. {
  219. [self example01];
  220. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
  221. self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
  222. }
  223. #pragma mark - 数据处理相关
  224. #pragma mark 下拉刷新数据
  225. - (void)loadNewData
  226. {
  227. // 1.添加假数据
  228. for (int i = 0; i<5; i++) {
  229. [self.data insertObject:MJRandomData atIndex:0];
  230. }
  231. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  232. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  233. // 刷新表格
  234. [self.tableView reloadData];
  235. // 拿到当前的下拉刷新控件,结束刷新状态
  236. [self.tableView.mj_header endRefreshing];
  237. });
  238. }
  239. #pragma mark 上拉加载更多数据
  240. - (void)loadMoreData
  241. {
  242. // 1.添加假数据
  243. for (int i = 0; i<5; i++) {
  244. [self.data addObject:MJRandomData];
  245. }
  246. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  247. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  248. // 刷新表格
  249. [self.tableView reloadData];
  250. // 拿到当前的上拉刷新控件,结束刷新状态
  251. [self.tableView.mj_footer endRefreshing];
  252. });
  253. }
  254. #pragma mark 加载最后一份数据
  255. - (void)loadLastData
  256. {
  257. // 1.添加假数据
  258. for (int i = 0; i<5; i++) {
  259. [self.data addObject:MJRandomData];
  260. }
  261. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  262. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  263. // 刷新表格
  264. [self.tableView reloadData];
  265. // 拿到当前的上拉刷新控件,变为没有更多数据的状态
  266. [self.tableView.mj_footer endRefreshingWithNoMoreData];
  267. });
  268. }
  269. #pragma mark 只加载一次数据
  270. - (void)loadOnceData
  271. {
  272. // 1.添加假数据
  273. for (int i = 0; i<5; i++) {
  274. [self.data addObject:MJRandomData];
  275. }
  276. // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码)
  277. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  278. // 刷新表格
  279. [self.tableView reloadData];
  280. // 隐藏当前的上拉刷新控件
  281. self.tableView.mj_footer.hidden = YES;
  282. });
  283. }
  284. - (NSMutableArray *)data
  285. {
  286. if (!_data) {
  287. self.data = [NSMutableArray array];
  288. for (int i = 0; i<5; i++) {
  289. [self.data addObject:MJRandomData];
  290. }
  291. }
  292. return _data;
  293. }
  294. #pragma mark - 其他
  295. - (void)viewDidLoad
  296. {
  297. [super viewDidLoad];
  298. self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  299. [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
  300. MJPerformSelectorLeakWarning(
  301. [self performSelector:NSSelectorFromString(self.method) withObject:nil];
  302. );
  303. }
  304. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  305. {
  306. return self.data.count;
  307. }
  308. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  309. {
  310. static NSString *ID = @"cell";
  311. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  312. if (cell == nil) {
  313. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
  314. }
  315. cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", indexPath.row % 2?@"push":@"modal", self.data[indexPath.row]];
  316. return cell;
  317. }
  318. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  319. {
  320. MJTestViewController *test = [[MJTestViewController alloc] init];
  321. if (indexPath.row % 2) {
  322. [self.navigationController pushViewController:test animated:YES];
  323. } else {
  324. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test];
  325. [self presentViewController:nav animated:YES completion:nil];
  326. }
  327. }
  328. @end