· 基本介绍
继承自UIScrollView,因此可以滚动。
需要Datasource
遵循UITableViewDataSource协议的OC对象,都可以是UITableView的数据源,该协议中的方法告诉UITableView如何显示数据。
关于UITableView
UITableView显示分组数据,对应方法numberOfxxx,若不实现,默认有1组数据。
每组显示几行几行数据:
每一组的每一行显示什么单元格内容:cellForRowAtIndexPath:创建cell一般在这里。
cell可以自定义。
设置数据源,需要让当前类声明协议。
多组数据时,设置行数:numberOfRowsInSection。通过if(section)数值来判断当前是第几组,然后设置当前组的行数。
每组的每行cell设置:cellForRowAtIndexPath:通过参数indexPath可以获取到section定位当前在哪个组里,然后设置当前组的cell样式,因为每个组的cell需要相同。根据indexPath.row可以获取到具体是哪一行。
还可以设置组标题、组尾描述。
关于组数:一般一组数据在plist中是一个项,即使多组在你的代码中,仍然用一个Array存,组数用array.count获取即可。
字典的模型化:
快速初始化赋值的方式:不必挨个从plist中按键读取,有提供的接口,根据字典参数即可: [setValuesForKeysWithDictionary: dict];
设置数据加载方式为懒加载:plist中读进来的数据在代码中是对象数组,该对象数组存的是对象,
类型是NSMutableArray,它可以添加任何类型的元素。
如果奇数行和偶数行行高不一样,需要通过代理来实现。如果一样,则通过统一的代理来实现。
各个单元格背景颜色也可以设置
在表格最上面和表格最下面(如加载更多),一般可以放【加载更多】这种样式的信息框使用(tableFooterVIew),顶部广告用(tableHeadView)。
· 学习目标:
学会给UITableView加载多组数据,单组数据。
学会复用cell,自定义cell。
Demo:分组显示TableView数据
TableView有两种样式:
分组的Group:注意每行行高都一致的设置。
不分组的Plain
# 设置数据源的方式
self.tableView.dataSource = self;
汽车品牌案例Demo(分组实现多组数据)
实现
1 准备数据plist和汽车icon
2 封装字典数据为模型
(1)声明数据模型,plist中各组为一个数据模型
@interface CZGroup : NSObject
// 组标题:使用copy防止意外被改变、线程安全
@property(nonatomic, copy) NSString *title;
// 组描述
@property(nonatomic, copy) NSString *desc;
// 组内车信息
@property(nonatomic, copy) NSArray *cars;
- (instancetype)initWithDict:(NSDictionary *)dict;
// 约定俗成:需要实现公有方法,类名+ WithDict
+ (instancetype)groupWithDict:(NSDictionary *)dict;
@end
(2)实现两个初始化方法,一个是传统初始化方法,一个是约定俗成的方法。
#import "CZGroup.h"
@implementation CZGroup
- (instancetype)initWithDict:(NSDictionary *)dict{
if(self = [super init]){
// KVC的写法:自动获取全部属性,并用字典的键赋值
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)groupWithDict:(NSDictionary *)dict{
return [[self alloc] initWithDict:dict];
}
@end
3 自定义UITableView
(1)该类需要实现数据源协议,故声明协议,再声明自定义属性:UITableView、装组数据的NSArray。
// 设置数据源需要声明协议
@interface UITableViewDemoCar : UIView<UITableViewDataSource>
@property(nonatomic, strong) UITableView *uitableview;
@property(nonatomic, strong) NSArray *groups;
@end
(2)实现
初始化组件、数据成员懒加载、实现数据源协议的相关方法
#import "UITableViewDemoCar.h"
#import "CZGroup.h"
@implementation UITableViewDemoCar
-(instancetype) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
// 初始化时指定好样式,分组数据类型还是单组数据类型:UITableViewStyleInsetGrouped是一种变种,高版本后引入的
// UITableViewStylePlain:某个组名,持续显示在上方 直到该组完全过去
_uitableview = [[UITableView alloc]initWithFrame:self.bounds style: UITableViewStyleGrouped];
_uitableview.dataSource = self;
// 懒加载必须通过self调用
self.groups;
}
// 开始没显示,因为没add
[self addSubview: _uitableview];
return self;
}
/*
数据描述:cars_simple中plist是数据、每个应该是组。
每个组下是不同类型的车
在定义cell内容的函数中触发懒加载
*/
#pragma mark - 数据懒加载
-(NSArray *)groups{
if(_groups == nil){
// 懒加载: 1, 获取plist 2. 创建对象数组 3. 添加到对象数组 4. 赋值对象数组给数据group
// 加载plist文件
NSString *path = [[NSBundle mainBundle] pathForResource:@"cars_simple.plist" ofType:nil];
// 创建字典
NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
// 创建数组
NSMutableArray *arrayModel = [NSMutableArray array];
// 根据字典内容创建每个模型,并加入数组
for(NSDictionary *dict in arrayDict){
// 创建模型对象
CZGroup *model = [CZGroup groupWithDict:dict];
[arrayModel addObject:model];
}
//
_groups = arrayModel;
}
return _groups;
}
#pragma mark - 协议相关样式
// 分几组
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return _groups.count;
}
// 每组几行,section为组号(每次遍历到这里,组号都不一样,加载一个UITableView会调用多次这个方法)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// 根据组号获取group,返回组中的车数
CZGroup *group = _groups[section];
return group.cars.count;
}
// 每一组的每一行的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 1. 获取模型数据:此处,触发懒加载,所以别在init中使用group
// 根据indexPath能获取到组号,而组号可以获取到数组中对应的数据模型,通过数据模型可以获取组内多行数据
CZGroup *group = self.groups[indexPath.section];
NSString *carBrand = group.cars[indexPath.row];
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = carBrand;
// 通过在cell上的属性可以直接给特定位置赋值,这些属性其实写好了坐标位置
//cell.textLabel.text = @"123";
//cell.imageView;
// cell.detailTextLabel
return cell;
}
// 设置组的标题
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
CZGroup *group = self.groups[section];
return group.title;
}
// 设置组末尾的描述信息
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
CZGroup *group = self.groups[section];
return group.desc;
}
// 设置组描述的数据源方法
@end