GKBaseListViewController.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. //
  2. // GKBaseListViewController.m
  3. // GKPageScrollViewDemo
  4. //
  5. // Created by QuintGao on 2018/12/11.
  6. // Copyright © 2018 QuintGao. All rights reserved.
  7. //
  8. #import "GKBaseListViewController.h"
  9. #import <MJRefresh/MJRefresh.h>
  10. #import <WebKit/WebKit.h>
  11. @interface GKBaseCollectionViewLayout : UICollectionViewFlowLayout
  12. @end
  13. @implementation GKBaseCollectionViewLayout
  14. - (CGSize)collectionViewContentSize {
  15. CGFloat minContentSizeHeight = self.collectionView.bounds.size.height;
  16. CGSize size = [super collectionViewContentSize];
  17. if (size.height < minContentSizeHeight) {
  18. return CGSizeMake(size.width, minContentSizeHeight);
  19. }
  20. return size;
  21. }
  22. @end
  23. @interface GKBaseListViewController()<UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate, WKNavigationDelegate>
  24. @property (nonatomic, strong) UIImageView *loadingView;
  25. @property (nonatomic, strong) UILabel *loadLabel;
  26. @property (nonatomic, copy) void(^listScrollViewScrollCallback)(UIScrollView *scrollView);
  27. @property (nonatomic, assign) GKBaseListType listType;
  28. @property (nonatomic, weak) UIScrollView *currentScrollView;
  29. @property (nonatomic, strong) UITableView *tableView;
  30. @property (nonatomic, strong) UICollectionView *collectionView;
  31. @property (nonatomic, strong) UIScrollView *scrollView;
  32. @property (nonatomic, strong) WKWebView *webView;
  33. @property (nonatomic, copy) void(^refreshCompletion)(void);
  34. @end
  35. @implementation GKBaseListViewController
  36. - (instancetype)initWithListType:(GKBaseListType)listType {
  37. if (self = [super init]) {
  38. self.listType = listType;
  39. }
  40. return self;
  41. }
  42. - (void)viewDidLoad {
  43. [super viewDidLoad];
  44. if (self.listType == GKBaseListType_UITableView) {
  45. [self.view addSubview:self.tableView];
  46. self.currentScrollView = self.tableView;
  47. }else if (self.listType == GKBaseListType_UICollectionView) {
  48. [self.view addSubview:self.collectionView];
  49. self.currentScrollView = self.collectionView;
  50. }else if (self.listType == GKBaseListType_UIScrollView) {
  51. [self.view addSubview:self.scrollView];
  52. self.currentScrollView = self.scrollView;
  53. }else if (self.listType == GKBaseListType_WKWebView) {
  54. [self.view addSubview:self.webView];
  55. self.currentScrollView = self.webView.scrollView;
  56. }
  57. if (self.listType == GKBaseListType_WKWebView) {
  58. [self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
  59. make.edges.equalTo(self.view);
  60. }];
  61. }else {
  62. [self.currentScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
  63. make.edges.equalTo(self.view);
  64. }];
  65. }
  66. if (self.listType != GKBaseListType_WKWebView && !self.disableLoadMore) {
  67. __weak __typeof(self) weakSelf = self;
  68. self.currentScrollView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
  69. __strong __typeof(weakSelf) self = weakSelf;
  70. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  71. [self loadMoreData];
  72. });
  73. }];
  74. }
  75. if (self.shouldLoadData) {
  76. [self.currentScrollView addSubview:self.loadingView];
  77. [self.currentScrollView addSubview:self.loadLabel];
  78. [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
  79. make.top.equalTo(self.currentScrollView).offset(40.0f);
  80. make.centerX.equalTo(self.currentScrollView);
  81. }];
  82. [self.loadLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  83. make.top.equalTo(self.loadingView.mas_bottom).offset(10.0f);
  84. make.centerX.equalTo(self.loadingView);
  85. }];
  86. self.count = 0;
  87. self.currentScrollView.mj_footer.hidden = self.count == 0;
  88. [self reloadData];
  89. [self showLoading];
  90. if (self.listType == GKBaseListType_WKWebView) {
  91. [self loadData];
  92. }else {
  93. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  94. [self hideLoading];
  95. [self loadData];
  96. });
  97. }
  98. }else {
  99. [self loadData];
  100. }
  101. }
  102. //- (void)viewWillAppear:(BOOL)animated {
  103. // [super viewWillAppear:animated];
  104. //
  105. // NSLog(@"%zd--%s", self.index, __func__);
  106. //}
  107. //
  108. //- (void)viewDidAppear:(BOOL)animated {
  109. // [super viewDidAppear:animated];
  110. //
  111. // NSLog(@"%zd--%s", self.index, __func__);
  112. //}
  113. //
  114. //- (void)viewWillDisappear:(BOOL)animated {
  115. // [super viewWillDisappear:animated];
  116. //
  117. // NSLog(@"%zd--%s", self.index, __func__);
  118. //}
  119. //
  120. //- (void)viewDidDisappear:(BOOL)animated {
  121. // [super viewDidDisappear:animated];
  122. //
  123. // NSLog(@"%zd--%s", self.index, __func__);
  124. //}
  125. - (void)viewWillLayoutSubviews {
  126. [super viewWillLayoutSubviews];
  127. if (!self.view.superview) return;
  128. if (CGSizeEqualToSize(self.view.superview.frame.size, CGSizeZero)) return;
  129. GKBaseCollectionViewLayout *layout = (GKBaseCollectionViewLayout *)self.collectionView.collectionViewLayout;
  130. CGFloat minW = MIN(self.view.superview.frame.size.width, self.view.superview.frame.size.width);
  131. layout.itemSize = CGSizeMake((minW - 60) / 2, (minW - 60) / 2);
  132. CGRect frame = self.view.frame;
  133. frame.size = self.view.superview.bounds.size;
  134. self.view.frame = frame;
  135. }
  136. - (void)loadData {
  137. if (self.count == 0) {
  138. self.count = 30;
  139. }
  140. if (self.listType == GKBaseListType_UIScrollView) {
  141. [self addCellToScrollView];
  142. }else if (self.listType == GKBaseListType_WKWebView) {
  143. [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://github.com/QuintGao/GKPageScrollView"]]];
  144. }
  145. [self reloadData];
  146. }
  147. - (void)loadMoreData {
  148. self.count += 20;
  149. if (self.count >= 100) {
  150. [self.currentScrollView.mj_footer endRefreshingWithNoMoreData];
  151. }else {
  152. [self.currentScrollView.mj_footer endRefreshing];
  153. }
  154. if (self.listType == GKBaseListType_UIScrollView) {
  155. [self addCellToScrollView];
  156. }
  157. [self reloadData];
  158. }
  159. - (void)addCellToScrollView {
  160. [self.scrollView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  161. if ([obj isKindOfClass:UILabel.class]) {
  162. [obj removeFromSuperview];
  163. }
  164. }];
  165. UIView *lastView = nil;
  166. for (NSInteger i = 0; i < self.count; i++) {
  167. UILabel *label = [UILabel new];
  168. label.textColor = [UIColor blackColor];
  169. label.font = [UIFont systemFontOfSize:16.0f];
  170. label.text = [NSString stringWithFormat:@"第%zd行", i + 1];
  171. [self.scrollView addSubview:label];
  172. [label mas_makeConstraints:^(MASConstraintMaker *make) {
  173. make.left.equalTo(@30);
  174. make.top.equalTo(lastView ? lastView.mas_bottom : @0);
  175. make.width.mas_equalTo(self.scrollView.mas_width);
  176. make.height.mas_equalTo(50.0f);
  177. }];
  178. lastView = label;
  179. }
  180. [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
  181. make.edges.equalTo(self.view);
  182. make.bottom.equalTo(lastView.mas_bottom);
  183. }];
  184. }
  185. - (void)showLoading {
  186. self.loadingView.hidden = NO;
  187. self.loadLabel.hidden = NO;
  188. [self.loadingView startAnimating];
  189. }
  190. - (void)hideLoading {
  191. [self.loadingView stopAnimating];
  192. self.loadingView.hidden = YES;
  193. self.loadLabel.hidden = YES;
  194. }
  195. - (void)addHeaderRefresh {
  196. __weak __typeof(self) weakSelf = self;
  197. self.currentScrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
  198. __strong __typeof(weakSelf) self = weakSelf;
  199. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  200. self.count = 30;
  201. [self reloadData];
  202. [self.currentScrollView.mj_header endRefreshing];
  203. !self.refreshCompletion ?: self.refreshCompletion();
  204. });
  205. }];
  206. }
  207. - (void)reloadData {
  208. if (self.listType == GKBaseListType_UITableView) {
  209. [self.tableView reloadData];
  210. }else if (self.listType == GKBaseListType_UICollectionView) {
  211. [self.collectionView reloadData];
  212. }
  213. }
  214. - (void)refreshWithCompletion:(nullable void(^)(void))completion {
  215. self.refreshCompletion = completion;
  216. [self.currentScrollView.mj_header beginRefreshing];
  217. }
  218. #pragma mark - UITableViewDataSource & UITableViewDelegate
  219. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  220. self.tableView.mj_footer.hidden = self.count == 0;
  221. return self.count;
  222. }
  223. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  224. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"listCell" forIndexPath:indexPath];
  225. cell.textLabel.text = [NSString stringWithFormat:@"第%zd行", indexPath.row + 1];
  226. return cell;
  227. }
  228. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  229. !self.listItemClick ?: self.listItemClick(self, indexPath);
  230. }
  231. #pragma mark - UICollectionViewDataSource, UICollectionViewDelegate
  232. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  233. self.collectionView.mj_footer.hidden = self.count == 0;
  234. return self.count;
  235. }
  236. - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  237. UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionViewCell" forIndexPath:indexPath];
  238. cell.contentView.backgroundColor = [UIColor redColor];
  239. [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  240. UILabel *textLabel = [UILabel new];
  241. textLabel.font = [UIFont systemFontOfSize:16.0f];
  242. textLabel.textColor = [UIColor blackColor];
  243. textLabel.text = [NSString stringWithFormat:@"第%zd", indexPath.item + 1];
  244. [cell.contentView addSubview:textLabel];
  245. [textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  246. make.center.equalTo(cell.contentView);
  247. }];
  248. return cell;
  249. }
  250. #pragma mark - WKNavigationDelegate
  251. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  252. NSLog(@"加载成功");
  253. [self hideLoading];
  254. }
  255. - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
  256. NSLog(@"加载失败");
  257. [self hideLoading];
  258. }
  259. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  260. !self.listScrollViewScrollCallback ? : self.listScrollViewScrollCallback(scrollView);
  261. }
  262. #pragma mark - GKPageListViewDelegate or GKPageSmoothListViewDelegate
  263. - (UIView *)listView {
  264. return self.view;
  265. }
  266. - (UIScrollView *)listScrollView {
  267. return self.currentScrollView;
  268. }
  269. - (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
  270. self.listScrollViewScrollCallback = callback;
  271. }
  272. - (UIImage *)changeImageWithImage:(UIImage *)image color:(UIColor *)color {
  273. UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
  274. CGContextRef context = UIGraphicsGetCurrentContext();
  275. CGContextTranslateCTM(context, 0, image.size.height);
  276. CGContextScaleCTM(context, 1.0, -1.0);
  277. CGContextSetBlendMode(context, kCGBlendModeNormal);
  278. CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
  279. CGContextClipToMask(context, rect, image.CGImage);
  280. [color setFill];
  281. CGContextFillRect(context, rect);
  282. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  283. UIGraphicsEndImageContext();
  284. return newImage;
  285. }
  286. - (void)listViewWillAppear {
  287. NSLog(@"%zd--%s", self.index, __func__);
  288. }
  289. - (void)listViewDidAppear {
  290. NSLog(@"%zd--%s", self.index, __func__);
  291. }
  292. - (void)listViewWillDisappear {
  293. NSLog(@"%zd--%s", self.index, __func__);
  294. }
  295. - (void)listViewDidDisappear {
  296. NSLog(@"%zd--%s", self.index, __func__);
  297. }
  298. #pragma mark - 懒加载
  299. - (UITableView *)tableView {
  300. if (!_tableView) {
  301. _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  302. _tableView.dataSource = self;
  303. _tableView.delegate = self;
  304. if (@available(iOS 11.0, *)) {
  305. _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  306. }
  307. [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"listCell"];
  308. }
  309. return _tableView;
  310. }
  311. - (UICollectionView *)collectionView {
  312. if (!_collectionView) {
  313. GKBaseCollectionViewLayout *layout = [GKBaseCollectionViewLayout new];
  314. layout.minimumLineSpacing = 20;
  315. layout.minimumInteritemSpacing = 20;
  316. CGFloat minW = MIN(self.view.frame.size.width, self.view.frame.size.height);
  317. layout.itemSize = CGSizeMake((minW - 60)/2, (minW - 60)/2);
  318. layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
  319. _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
  320. _collectionView.dataSource = self;
  321. _collectionView.delegate = self;
  322. [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"collectionViewCell"];
  323. _collectionView.backgroundColor = [UIColor whiteColor];
  324. if (@available(iOS 11.0, *)) {
  325. _collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  326. }
  327. _collectionView.alwaysBounceVertical = YES;
  328. }
  329. return _collectionView;
  330. }
  331. - (UIScrollView *)scrollView {
  332. if (!_scrollView) {
  333. _scrollView = [[UIScrollView alloc] init];
  334. _scrollView.delegate = self;
  335. if (@available(iOS 11.0, *)) {
  336. _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  337. }
  338. _scrollView.backgroundColor = [UIColor whiteColor];
  339. _scrollView.alwaysBounceVertical = YES;
  340. }
  341. return _scrollView;
  342. }
  343. - (WKWebView *)webView {
  344. if (!_webView) {
  345. WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
  346. _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
  347. _webView.scrollView.delegate = self;
  348. if (@available(iOS 11.0, *)) {
  349. _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  350. }
  351. _webView.navigationDelegate = self;
  352. }
  353. return _webView;
  354. }
  355. - (UIImageView *)loadingView {
  356. if (!_loadingView) {
  357. NSMutableArray *images = [NSMutableArray new];
  358. for (NSInteger i = 0; i < 4; i++) {
  359. NSString *imageName = [NSString stringWithFormat:@"cm2_list_icn_loading%zd", i + 1];
  360. UIImage *img = [self changeImageWithImage:[UIImage imageNamed:imageName] color:RGB(200, 38, 39)];
  361. [images addObject:img];
  362. }
  363. for (NSInteger i = 4; i > 0; i--) {
  364. NSString *imageName = [NSString stringWithFormat:@"cm2_list_icn_loading%zd", i];
  365. UIImage *img = [self changeImageWithImage:[UIImage imageNamed:imageName] color:RGB(200, 38, 39)];
  366. [images addObject:img];
  367. }
  368. UIImageView *loadingView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 20.0f, 20.0f)];
  369. loadingView.animationImages = images;
  370. loadingView.animationDuration = 0.75;
  371. loadingView.hidden = YES;
  372. _loadingView = loadingView;
  373. }
  374. return _loadingView;
  375. }
  376. - (UILabel *)loadLabel {
  377. if (!_loadLabel) {
  378. _loadLabel = [UILabel new];
  379. _loadLabel.font = [UIFont systemFontOfSize:14.0f];
  380. _loadLabel.textColor = [UIColor grayColor];
  381. _loadLabel.text = @"正在加载...";
  382. _loadLabel.hidden = YES;
  383. }
  384. return _loadLabel;
  385. }
  386. @end