· 基本介绍
继承自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.detailTextLabelreturn 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