6、UITableView
简介:
Table其实就是表格的意思,而UITableView更是我们UI学习的重点。
其实在众多移动应用中,我们可以看到各式各样的表格数据,例如:App管理应用表格、QQ好友列表等。。。
我们的UITableView是继承自我们的UIScrollView的,因此支持滚动,而且性能极佳,但是默认为垂直滚动。
在iOS开发中,要想是实现表格数据展示,常用的做法就是使用UITableView
注意:
表格——就是格式一样,显示的内容不一样。
例如之前我们写的一个<应用管理>程序中的xib,他们的结构、格式都一样,只是显示的数据不一样。
6.1多组数据--基本使用
我们的表格分两种:
1、分组(UITableViewStyleGrouped)
2、不分组(UITableViewStylePlain)
利用汽车品牌展示程序,介绍UITableView
做程序首先看效果:
这个上面显示的是汽车的品牌名、以及系列
我们就是利用UITableView做出的一个程序界面
下面就开始写代码
1、在我们的storyboard上面添加一个TableView
2、将我们的数据显示到TableView上
注意:
如何添加???
1、其实我们的UITableView需要一个数据源(dataSource)来显示数据
2、UITableView会像数据源发送一条消息,查询一共有多少行数据,以及每一行显示什么数据等
3、没有数据源的UITableView只是一个空壳
4、凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源
1、设置添加数据首先遵守协议
#import "ViewController.h"
@interface ViewControlloer ()
//将我们的TableView变成这个属性
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
2、设置数据源
注意:
首先我们要了解我们数据源的几个方法:
给我们的表格查找数据一个渠道
- (void)viewDidLoad()
{
[super viewDidLoad];
//设置数据源
self.tableView.dataSource = self;
}
3、设置我们的表格需要多少组
- (NSInteger)numberOfSectionInTableView:(UITableView *)taableView
{
//代表的是两组数据
return 2;
}
4、设置第section组有多少行(由上面的方法可以得知的是,我们的这个4这个方法是要被调用两次的)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0){
return 3;
} else{
return 4;
}
}
解释:UITableView一旦查找数据源的时候,数据源首先调用3这个方法,表示一共有两组,然后第0组是有3几行,方法4就会返回一个3,表示第0组有3行,第二次调用的时候section返回的是1,表示第1组有4行。
5、该行要显示的数据
/**
* 每一行显示怎样的内容(cell)
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
if (indexPath.section == 0) { // 德系品牌(第0组)
if (indexPath.row == 0) { // 第0组的第0行
cell.textLabel.text = @"奥迪";
} else if (indexPath.row == 1) { // 第0组的第1行
cell.textLabel.text = @"宝马";
} else if (indexPath.row == 2) {
cell.textLabel.text = @"奔驰";
}
} else if (indexPath.section == 1) { // 日韩品牌(第1组)
if (indexPath.row == 0) { // 第1组的第0行
cell.textLabel.text = @"本田";
} else if (indexPath.row == 1) { // 第1组的第1行
cell.textLabel.text = @"丰田";
} else if (indexPath.row == 2) {
cell.textLabel.text = @"铃木";
} else if (indexPath.row == 3) {
cell.textLabel.text = @"三菱";
}
}
return cell;
}
6、显示每一组的头部与尾部的信息
/**
* 第section组显示怎样的头部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return @"德系品牌";
} else if (section == 1) {
return @"日韩品牌";
} else {
return @"欧系品牌";
}
}
/**
* 第section组显示怎样的尾部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if (section == 0) {
return @"世界一流品牌";
} else if(section == 1) {
return @"牛逼哄哄";
} else {
return @"价格昂贵";
}
}
注意:
1、我们的UITableView中每一行的其实就是我们的UITableViewCell,而这个
所以我们在设置数据的时候,我们需要写一个方法
2、在我们每一行显示的内容的中,如何准确的将我们想显示的数据显示到对应行里所以我们方法里面提供一个参数 :
indexPath准确定位于唯一的那一行
indexPath.section==0代表的就是第0组
indexPath.row==0代表的是第0行
上面综合表示的就是第0组的第0行要显示那些数据
我们的indexPath就是
一般的当我们遇到很多if()else这样类似的语句的时候,我们是可以抽取,使我们的代码变得更加简洁
以上是我们基础的UITableView的使用,下面我们就来介绍其他的几种较为简单的方法
前言:上面的代码,不仅全是if() else之类的,更重要的是,上面代码的扩展性不是很好,一旦我们新增加一组,就意味着所有的代码都要修改。所以需要重构代码:
观察代码,我们发现有一个共同的特点:他们都是由头标、品牌名称、尾标,这三个部分组成的,再加上之前学习的内容,我们可以联想到利用模型将我们的代码重构
做法:
1、创建一个模型,名称为carGroup
回忆:
模型—————我们创建的一个用来存放一些数据的类,就叫做模型类,也就是模型
这个模型中有三个属性分别是:
#import
@interface carGroup :NSObject
/**
* 头部标题
*/
@property (nonatomic, copy) NSString *title;
/**
* 尾部标题(描述)
*/
@property (nonatomic, copy) NSString *desc;
/**
* 这组的所有车(字符串)
*/
@property (nonatomic, strong) NSArray *cars;
@end
上面的属性是NSString类型的
2、改写控制器中的代码
1、写上头文件
#import "ViewController.h"
#import "carGroup.h"
2、让carGroup成为控制器的属性:
@property (nonatomic, strong) NSArray *carGroups;
3、在我们的模型中添加数据:
- (NSArray *)carGroups
{
if (_carGroups == nil) {
// 初始化
// 德系品牌
MJCarGroup *cg1 = [[MJCarGroup alloc] init];
cg1.title = @"德系品牌";
cg1.desc = @"德系品牌很好";
cg1.cars = @[@"奥迪", @"宝马", @"奔驰"];
// 日韩品牌
MJCarGroup *cg2 = [[MJCarGroup alloc] init];
cg2.title = @"日韩品牌";
cg2.desc = @"日韩品牌很好haohaohao";
cg2.cars = @[@"本田", @"丰田"];
// 欧系品牌
MJCarGroup *cg3 = [[MJCarGroup alloc] init];
cg3.title = @"欧系品牌";
cg3.desc = @"欧系品牌goodgood";
cg3.cars = @[@"兰博基尼", @"法拉利"];
_carGroups = @[cg1, cg2, cg3];
}
return _carGroups;
}
4、TableView确定有多少组。
- (NSInTeger) numberOfSectionsInTableView(UITableView *)tableView
{
return self.carGroup.count;
}
5、确定第section组共有多少行
- (NSInTeger)thableView:(UITableView *)tableView numberOfRowInSection:(NSInteger)section
{
// 取得第section组对应的模型
MJCarGroup *cg = self.carGroups[section];
return cg.cars.count;
}
6、每一行显示的内容cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// 取出第indexPath.section组对应的模型
MJCarGroup *cg = self.carGroups[indexPath.section];
// 取车第indexPath.row这行对应的品牌名称
NSString *car = cg.cars[indexPath.row];
// 设置cell显示的文字
cell.textLabel.text = car;
return cell;
}
7、头标
/**
* 第section组显示怎样的头部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
MJCarGroup *cg = self.carGroups[section];
return cg.title;
}
8、尾标
/**
* 第section组显示怎样的尾部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
MJCarGroup *cg = self.carGroups[section];
return cg.desc;
}
这个就是我们代码重构之后的样子,这里面的优点:如果我们想增加一组数据、减少一组数据,只需要更改模型里面的数据,就行了
这里面有点我们的MVC的思想,一旦模型数据改变,View会跟着改变
注意:
当你自己写代码的时候可能会和展示的效果图不一样:
原因就是我们在设置TableView的时候所选选项不一样:
上面中:Grouped造成的结果就是右边的效果图(即是前面所介绍的效果图,Plain就是左边的图片)
两者的特点
plain
1、当我们的分组中没有了尾标(买描述)的时候他的显示效果同样不错
2、注意的是
当分组中汽车品牌的种类较多(一个屏幕放不下)的时候
我们的这个头标就会一直存在,直到遇到下一个头标,将该头标顶上去
eg:手机联系人中按照第一个字的首字母排序的时候,一旦联系人由A~B的时候,这时候B就会把A给顶上去。
而这个Grouped没有这个效果
而我们常用的就是利用plist
文件来完成我们的数据加载
作者说:
这个是我们的关于TableView
一些简单的用法, 所以今天先介绍到这里, 而且我感觉代码也没必要上传了(其实是我的代码很乱而已), 下一篇文章, 介绍的是单组数据的展示lol英雄展示