iOS开发UI篇—在UItableview中实现加载更多功能
一、实现效果
点击加载更多按钮,出现一个加载图示,三秒钟后添加两条新的数据。
二、实现代码和说明
当在页面(视图部分)点击加载更多按钮的时候,主页面(主控制器)会加载两条数据进来。
视图部分的按钮被点击的时候,要让主控制器加载数据,刷新表格,2B青年会在视图中增加一个主控制器的属性,通过这个属性去调用进行加载,但在开发中通常通过代理模式来完成这个操作。
下面分别是两种实现的代码。
1、项目结构和说明
说明:加载更多永远都放在这个tableview的最下端,因此这里设置成了这个tableview的tableFooterView。
self.tableview.tableFooterView=footerview;
在实现上通过xib来进行处理,考虑到左右的留白,以及点击后的要切换到加载按钮和文字,要同时控制图标和文字,因此把加载图标和文字提示放在了一个view中以便控制,这个xib已经和YYfooterview.xib进行了关联,通过这个类来控制xib。
2、实现代码
(1).垃圾代码
数据模型部分
TXtg.h文件
1 // Created by 鑫 on 14-10-8.
2 // Copyright (c) 2014年 梁镋鑫. All rights reserved.
3 //
4
5 #import <Foundation/Foundation.h>
6
7 @interface TXTg : NSObject
8 /**
9 * 标题
10 */
11 @property(nonatomic,copy)NSString *title;
12 /**
13 * 价格
14 */
15 @property(nonatomic,copy)NSString *price;
16 /**
17 * 图片
18 */
19 @property(nonatomic,copy)NSString *icon;
20 /**
21 * 购买人数
22 */
23 @property(nonatomic,copy)NSString *buyCount;
24 -(instancetype)initWithDict:(NSDictionary *)dict;
25 +(instancetype)tgWithDict:(NSDictionary *)dict;
26 @end
TXtg.m文件
1 #import "TXTg.h"
2
3 @implementation TXTg
4 -(instancetype)initWithDict:(NSDictionary *)dict;
5 {
6 if (self = [super init]) {
7 [self setValuesForKeysWithDictionary:dict];
8 }
9 return self;
10 }
11 +(instancetype)tgWithDict:(NSDictionary *)dict
12 {
13 return [[self alloc]initWithDict:dict];
14
15 }
16 @end
视图部分
TXtgcell.h文件
1 // 屌丝逆天记-团购-01
2 //
3 // Created by 鑫 on 14-10-8.
4 // Copyright (c) 2014年 梁镋鑫. All rights reserved.
5 //
6
7 #import <UIKit/UIKit.h>
8 @class TXTg;
9 @interface TXTgCell : UITableViewCell
10 /**
11 * 通过一个tableview来创建一个cell
12 */
13 +(instancetype)cellWithTableView:(UITableView *)tableView;
14 /**
15 * 团购模型
16 */
17 @property(nonatomic ,strong)TXTg *tg;
18
19 @end
TXtgcell.m文件
1 #import "TXTgCell.h"
2 #import "TXTg.h"
3 @interface TXTgCell()
4 @property (weak, nonatomic) IBOutlet UIImageView *iconView;
5 @property (weak, nonatomic) IBOutlet UILabel *titleView;
6 @property (weak, nonatomic) IBOutlet UILabel *priceView;
7 @property (weak, nonatomic) IBOutlet UILabel *buyCountView;
8
9 @end
10 @implementation TXTgCell
11 +(instancetype)cellWithTableView:(UITableView *)tableView
12 {
13 static NSString *ID =@"tg";
14 TXTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
15 if (cell ==nil) {
16 //从xib中加载cell
17 cell = [[[NSBundle mainBundle] loadNibNamed:@"TXTgCell" owner:nil options:nil] lastObject];
18 }
19 return cell;
20 }
21 -(void)setTg:(TXTg *)tg
22 {
23 _tg = tg;
24
25 //图片
26 self.iconView.image = [UIImage imageNamed:tg.icon];
27 self.titleView.text = tg.title;
28 self.priceView.text = [NSString stringWithFormat:@"¥%@",tg.price];
29
30 self.buyCountView.text = [NSString stringWithFormat:@"%@人已购买", tg.buyCount];
31 }
32
33
34
35 @end
TXTgFooterView.h文件
1 #import <UIKit/UIKit.h>
2 @class TXViewController;
3 @interface TXTgFooterView : UIView
4 /**
5 * 快速创建一个footerView对象
6
7 */
8 +(instancetype )footerView;
9 @property(nonatomic ,strong)TXViewController *controller;
10
11 @end
TXTgFooterView.m文件
1 #import "TXTgFooterView.h"
2 #import "TXViewController.h"
3 @interface TXTgFooterView()
4 @property (weak, nonatomic) IBOutlet UIButton *loadBtn;
5 @property (weak, nonatomic) IBOutlet UIView *loadingView;
6
7 @end
8 @implementation TXTgFooterView
9 +(instancetype)footerView
10 {
11 return [[[NSBundle mainBundle] loadNibNamed:@"TXTgFooterView" owner:nil options:nil] lastObject];
12 }
13 - (IBAction)loadBtnClick {
14 //隐藏加载按钮
15 self.loadBtn.hidden = YES;
16 //显示正在加载
17 self.loadingView.hidden = NO;
18
19 //显示更多按钮
20 //GCD延迟加载
21
22 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{// 3.0s后执行block里面的代码
23
24 [self.controller loadingMoreData];
25
26 // 4.显示加载按钮
27 self.loadBtn.hidden = NO;
28
29 // 5.隐藏"正在加载"
30 self.loadingView.hidden = YES;
31
32 });
33
34
35
36 }
37
38
39 @end
主控制器
TXViewController.h文件
1 #import <UIKit/UIKit.h>
2
3 @interface TXViewController : UIViewController
4 - (void)loadingMoreData;
5 @end
TXViewController.m文件
1 #import "TXViewController.h"
2 #import "TXTg.h"
3 #import "TXTgCell.h"
4 #import "TXTgFooterView.h"
5 @interface TXViewController ()<UITableViewDataSource>
6 @property (weak, nonatomic) IBOutlet UITableView *tableview;
7
8 @property(nonatomic ,strong)NSMutableArray *tgs;
9
10 @end
11
12 @implementation TXViewController
13
14 - (void)viewDidLoad
15 {
16 [super viewDidLoad];
17 //设置每一行cell的高度
18 self.tableview.rowHeight =80;
19
20 //设置footerView
21 TXTgFooterView * footer = [TXTgFooterView footerView];
22 footer.controller = self;
23 self.tableview.tableFooterView = footer;
24
25 }
26 /**
27 * 隐藏状态栏
28 */
29 - (BOOL)prefersStatusBarHidden
30 {
31 return YES;
32 }
33 /**
34 * 数据的懒加载
35 */
36 -(NSMutableArray *)tgs
37 {
38 if (_tgs ==nil) {
39 //初始化
40 NSString *path = [[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil];
41 //加载数组
42
43 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
44
45 //3.将dictArray里面的所有字典转成模型对象,放到新的数组中
46 NSMutableArray *tgArray = [NSMutableArray array];
47
48 for (NSDictionary *dict in dictArray) {
49 //创建模型对象
50 TXTg *tg = [TXTg tgWithDict:dict];
51
52 // 加载模型对象倒数组中
53 [tgArray addObject:tg];
54
55 }
56 _tgs = tgArray;
57
58 }
59 return _tgs;
60 }
61 /**
62 * 加载更多的数据
63 */
64 -(void)loadingMoreData
65 {
66 //添加更多模型数据
67 TXTg *tg = [[TXTg alloc]init];
68 tg.icon =@"ad_01";
69 tg.title = @"jsfsdfjjsd";
70 tg.price = @"100";
71 tg.buyCount = @"0";
72 [self.tgs addObject:tg];
73 // 2.刷新表格(告诉tableView重新加载模型数据, 调用tableView的reloadData)
74 [self.tableview reloadData];
75
76 }
77
78 #pragma mark --数据源方法
79 /**
80 * 一共多少行
81 */
82 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
83 {
84 return self.tgs.count;
85 }
86 /**
87 * 每一行显示怎样的cell
88 */
89 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
90 {
91 //创建cell
92 TXTgCell *cell = [TXTgCell cellWithTableView:tableView];
93
94 //给cell传递模型数据
95 cell.tg = self.tgs[indexPath.row];
96 return cell;
97 }
98 - (void)didReceiveMemoryWarning
99 {
100 [super didReceiveMemoryWarning];
101 // Dispose of any resources that can be recreated.
102 }
103
104 @end
2.通过代理完成
当按钮被点击的时候,视图部分本身不干活,而是通知它的代理(控制器)完成接下来的操作。
该部分代码在1的基础上对下面几个文件进行了修改:
视图部分:
TXTgFooterView.h文件
1 #import <UIKit/UIKit.h>
2 @class TXTgFooterView;
3 /**
4 1.协议名称: 控件类名 + Delegate
5 2.代理方法普遍都是@optional
6 3.
7 */
8 @protocol TXTfFooterViewDelegate <NSObject>
9
10 @optional
11 -(void)tgFooterViewDidClickedLoadBtn:(TXTgFooterView *)tgFooterView;
12
13 @end
14
15
16 @interface TXTgFooterView : UIView
17
18 /**
19 * 快速创建一个footerView对象
20 */
21 + (instancetype)footerView;
22
23 //定义一个代理,这个代理必须实现<TXTgFooterViewDelegate>这个协议
24 @property(nonatomic,weak) id <TXTfFooterViewDelegate> delegate;
25
26
27 @end
TXTgFooterView.m文件
1 #import "TXTgFooterView.h"
2 #import "TXViewController.h"
3
4 @interface TXTgFooterView()
5 - (IBAction)loadBtnClick;
6 @property (weak, nonatomic) IBOutlet UIButton *loadBtn;
7 @property (weak, nonatomic) IBOutlet UIView *loadingView;
8 @end
9
10 @implementation TXTgFooterView
11
12 + (instancetype)footerView
13 {
14 return [[[NSBundle mainBundle] loadNibNamed:@"TXTgFooterView" owner:nil options:nil] lastObject];
15 }
16
17 /**
18 * 点击"加载"按钮
19 */
20 - (IBAction)loadBtnClick {
21 // 1.隐藏加载按钮
22 self.loadBtn.hidden = YES;
23
24 // 2.显示"正在加载"
25 self.loadingView.hidden = NO;
26
27 // 3.显示更多的数据
28 // GCD
29 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 3.0s后执行block里面的代码
30 if ([self.delegate respondsToSelector:@selector(tgFooterViewDidClickedLoadBtn:)]) {
31 [self.delegate tgFooterViewDidClickedLoadBtn:self];
32 }
33 // 4.显示加载按钮
34 self.loadBtn.hidden = NO;
35
36 // 5.隐藏"正在加载"
37 self.loadingView.hidden = YES;
38 });
39 }
40 @end
主控制器部分
TXViewController.h文件
1 #import <UIKit/UIKit.h>
2
3 @interface TXViewController : UIViewController
4 - (void)loadingMoreData;
5 @end
TXViewController.m文件
1 #import "TXViewController.h"
2 #import "TXTg.h"
3 #import "TXTgCell.h"
4 #import "TXTgFooterView.h"
5 #import "TXTXTgHeaderView.h"
6 @interface TXViewController () <UITableViewDataSource,TXTfFooterViewDelegate>
7 @property (weak, nonatomic) IBOutlet UITableView *tableView;
8 @property (nonatomic, strong) NSMutableArray *tgs;
9 @end
10
11 @implementation TXViewController
12
13 - (void)viewDidLoad
14 {
15 [super viewDidLoad];
16
17 // 设置每一行cell的高度
18 self.tableView.rowHeight = 80;
19
20 // 设置footerView
21 TXTgFooterView *footer = [TXTgFooterView footerView];
22 footer.delegate =self;
23 self.tableView.tableFooterView = footer;
24
25
26 //设置headerView
27 self.tableView.tableHeaderView = [TXTXTgHeaderView headerView];
28
29 // 设置tableView尾部显示的控件(tableFooterView的宽度永远是tableView的宽度)
30 // tableFooterView只需要设置高度
31 // UIButton *footerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
32 // footerBtn.frame = CGRectMake(0, 0, 0, 35);
33 // footerBtn.backgroundColor = [UIColor orangeColor];
34 // [footerBtn setTitle:@"加载更多团购" forState:UIControlStateNormal];
35
36 // UINib *nib = [UINib nibWithNibName:@"TXTgFooterView" bundle:[NSBundle mainBundle]];
37
38 // 创建nib对象
39 // UINib *nib = [UINib nibWithNibName:@"TXTgFooterView" bundle:nil];
40 //
41 // // 加载xib\nib
42 // UIView *footerView = [[nib instantiateWithOwner:nil options:nil] lastObject];
43 // self.tableView.tableFooterView = footerView;
44 }
45
46 /**
47 * 加载更多的数据
48 */
49 - (void)tgFooterViewDidClickedLoadBtn:(TXTgFooterView *)tgFooterView
50 {
51 #warning 正常开发:发送网络请求给远程的服务器
52 // 1.添加更多的模型数据
53 TXTg *tg = [[TXTg alloc] init];
54 tg.icon = @"ad_01";
55 tg.title = @"新增加的团购数据..";
56 tg.price = @"100";
57 tg.buyCount = @"0";
58 [self.tgs addObject:tg];
59
60 // 2.刷新表格(告诉tableView重新加载模型数据, 调用tableView的reloadData)
61 [self.tableView reloadData];
62 }
63
64 /**
65 * 隐藏状态栏
66 */
67 - (BOOL)prefersStatusBarHidden
68 {
69 return YES;
70 }
71
72 /**
73 * 数据的懒加载
74 */
75 - (NSMutableArray *)tgs
76 {
77 if (_tgs == nil) {
78 // 初始化
79 // 1.获得plist的全路径
80 NSString *path = [[NSBundle mainBundle] pathForResource:@"tgs.plist" ofType:nil];
81
82 // 2.加载数组
83 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
84
85 // 3.将dictArray里面的所有字典转成模型对象,放到新的数组中
86 NSMutableArray *tgArray = [NSMutableArray array];
87 for (NSDictionary *dict in dictArray) {
88 // 3.1.创建模型对象
89 TXTg *tg = [TXTg tgWithDict:dict];
90
91 // 3.2.添加模型对象到数组中
92 [tgArray addObject:tg];
93 }
94
95 // 4.赋值
96 _tgs = tgArray;
97 }
98 return _tgs;
99 }
100
101 #pragma mark - 数据源方法
102 /**
103 * 一共有多少行数据
104 */
105 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
106 {
107 return self.tgs.count;
108 }
109
110 /**
111 * 每一行显示怎样的cell
112 */
113 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
114 {
115 // 1.创建cell
116 TXTgCell *cell = [TXTgCell cellWithTableView:tableView];
117
118 // 2.给cell传递模型数据
119 cell.tg = self.tgs[indexPath.row];
120 return cell;
121 }
122 @end