MJTableViewController.m 14 KB

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