1. UITableView:
1. UITableView 继承于 UIScrollView 所以可以滚动
2. 控制器需要遵守两个协议:<UITableViewDelegate,UITableViewDataSource>
section:分组 row:行
1.1 UITableView的代理方法:
属性(常用):
imageView:用来添加图片
textLabel:添加文本框
detailTextLabel:当style设置为UITableViewCellStyleValue1时,这个是详细信息的限时,放在textLabel下面
(还有很多,之前都学过的属性)
UITableView最多就是代理方法
1. 必须实现的代理方法:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section :记住返回类型和前几个字母就可以了---每个分组的行数
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath ——单元格的内容
2. 选择性实现:
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 同样用的时候记住返回值和table就可以了——分组的多少
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath——选中cell响应的事件 和didDeselect...不一样,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath——行高
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView——右侧的索引 (可以自己写)
- (void)viewDidLoad {
[super viewDidLoad];
// 之前学的控制器的Title:
self.title = @"The list";
// 给两个协议设置代理------<UITableViewDelegate,UITableViewDataSource>
self.rootV.tableView.delegate = self;
self.rootV.tableView.dataSource = self; // dataSource数据源
}
#pragma mark =========================以下这些代理方法是必须实现的~ ~ ~==========================
#pragma mark-------- *** 1 *** 在每个分组中有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 确定有多少行 注意:是在一个分组中就有这么多行啦
return 5;
}
#pragma mark------- *** 2 *** 设置每行(cell)的内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
#pragma mark------cell的初始化
// 创建一个cell
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
#pragma mark------cell的属性
// 设置cell的属性
if (indexPath.row % 2 == 0) {// indexPath是当前的行号 传进来的数值
cell.textLabel.text = @"Coco";
cell.detailTextLabel.text = @"hahahah";
cell.imageView.image = [UIImage imageNamed:@"1.png"];
}else {
cell.textLabel.text = @"zhaozilong";
cell.detailTextLabel.text = @"ba qi";
cell.imageView.image = [UIImage imageNamed:@"2.jpeg"];
}
// cell.imageView.frame = CGRectMake(0, 20, 20, 20); // 这个设置无效
return cell;
}
#pragma mark ===========================以下的方法是可选的哦~ ~ ~===============================
#pragma mark----- *** 1 *** 设置有多少组(sections)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
#pragma mark----- *** 2 *** cell的点击响应事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 分组和行都是从0开始
NSLog(@"%ld组, %ld行", indexPath.section, indexPath.row);
}
#pragma mark----- *** 3 *** 设置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
#pragma mark----- *** 4 *** 设置头视图:返回视图
// 下面两个结合使用 只用第一个的话,第一组的就没有头视图,高度也不对
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
view.backgroundColor = [UIColor orangeColor];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
label.backgroundColor = [UIColor whiteColor];
label.text = @"张--Z";
[view addSubview:label];
// 创建一个视图,并返回这个视图就可以显示在section的header位置了
// 要和下面设置header高度的方法一起使用!!!!
// 可以直接返回label 显示的时候就只有一个label了
return view;
}
#pragma mark-----设置头视图的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
// 要是不想看到头视图 就把高度设置成0.1或者其他 如果设置成0,会显示默认的高度
return 50;
}
#pragma mark----- *** 5 *** 设置尾视图及高度:
// 同样要设置尾视图的高度 两个方法结合使用
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = [UIColor blueColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 50;
}
#pragma mark----- *** 6 *** 右侧竖排的索引:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
return array;
}
注意:要是不想看到头视图 就把高度设置成0.1或者其他 如果设置成0,会显示默认的高度
初始化tableView的时候:写成UITableViewStyleGrouped才能看到分组效果
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(50, 50, 300, 400) style:UITableViewStyleGrouped];
1.2 UITableView的优化:cell重用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// =====1. 这个是不重用的写法:每次都需要创建一个新的cell=====
// UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
// =====2. 这个是重用的写法:写法有点麻烦=====
static NSString *cell_id = @"cell_id";
// @"cell_id"只是一个标识,可以随便写其他的字符串
// 从重用池里面选取cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
// 判断重用池中是否有可用的cell 结果为空:再创建一个新的 不为空:直接拿出来用
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
cell.textLabel.text = self.arrayData[indexPath.section][indexPath.row];
// 选中某个cell之后的样式
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
// 右边的辅助样式
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
/*
UITableViewCellAccessoryNone, // nothing
UITableViewCellAccessoryDisclosureIndicator, // 三角标
UITableViewCellAccessoryDetailDisclosureButton, // 三角标和叹号按钮
UITableViewCellAccessoryCheckmark, // 对勾
UITableViewCellAccessoryDetailButton // 叹号按钮
*/
return cell;
}
1.3 补充属性:
separatorColor separatorStyle:分割线的颜色和样式
selectionStyle:选中cell的样式
accessoryType:右侧索引样式
实现:点击第一个界面的某一行,将对应的文字传到第二个界面
ViewController.m:
@interface ViewController ()
@property (nonatomic,strong) NSMutableArray *arrayData;
@property (nonatomic,strong) NSMutableArray *arrayTitle;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStyleGrouped];
[self.view addSubview:self.tableView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
// 分割线的颜色
self.tableView.separatorColor = [UIColor blackColor];// 分割线加上颜色太丑啦
// 分割线的样式
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
// 设置一维数组:
// self.arrayData = [NSMutableArray arrayWithObjects:@"葵花宝典", @"六脉神剑", @"降龙十八掌", @"独孤九剑", @"铁砂掌", @"轻功水上漂", @"吸星大法", @"一阳指", nil];
// 设置二维数组 可以分组显示
self.arrayData = [NSMutableArray array];
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"爱新觉罗.玄烨", @"阿童木", @"阿凡达", @"奥利奥", @"阿凡提", @"阿狗", @"奥斯特洛夫斯基", nil];
NSMutableArray *array2 = [NSMutableArray arrayWithObjects:@"毕福剑", @"包贝尔", @"白素贞", @"弼马温", @"毕昇", @"宝宝", @"粑粑", nil];
NSMutableArray *array3 = [NSMutableArray arrayWithObjects:@"曹操", @"曹雪芹", @"陈真", @"成龙", @"coca-cola", nil];
self.arrayData = [NSMutableArray arrayWithObjects:array1, array2, array3, nil];
self.arrayTitle = [NSMutableArray arrayWithObjects:@"A", @"B", @"C", nil];
}
// 必须实现的两个方法:设置多少行 设置cell内容
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 一维数组的行数:
// return self.arrayData.count;
// 二维数组的行数
return [self.arrayData[section] count];
}
// 设置单元格内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
#pragma =====1. 这个是不重用的写法:每次都需要创建一个新的cell=====
// UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
#pragma =====2. 这个是重用的写法:写法有点麻烦=====
static NSString *cell_id = @"cell_id";
// @"cell_id"只是一个标识,可以随便写其他的字符串
// 从重用池里面选取cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
// 判断重用池中是否有可用的cell 结果为空:再创建一个新的 不为空:直接拿出来用
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
cell.textLabel.text = self.arrayData[indexPath.section][indexPath.row];
// 选中某个cell之后的样式
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
// 右边的辅助样式 类似于索引
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
/*
UITableViewCellAccessoryNone, // nothing
UITableViewCellAccessoryDisclosureIndicator, // 三角标
UITableViewCellAccessoryDetailDisclosureButton, // 三角标和叹号按钮
UITableViewCellAccessoryCheckmark, // 对勾
UITableViewCellAccessoryDetailButton // 叹号按钮
*/
return cell;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.arrayData.count;
}
// 设置头视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
label.text = self.arrayTitle[section];
label.textAlignment = NSTextAlignmentCenter;
return label;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
// 头视图的高度
return 20;
}
// 设置右侧的索引栏
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.arrayTitle;
}
#pragma mark---------点击某行的响应事件事件------点击单元格响应事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SecondViewController *secondVC = [[SecondViewController alloc] init];
// 页面跳转的样式
secondVC.modalTransitionStyle = UIModalTransitionStylePartialCurl;
secondVC.sendMessage = self.arrayData[indexPath.section][indexPath.row];
// 模态是控制器的方法,不需要navigationController
[self presentViewController:secondVC animated:YES completion:nil];
}
// 单元格的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
2. UITableView 编辑:
3.UITableView 自定义cell 自适应 model:
3.1 自定义cell:
只要用到UITableView就要遵守协议:<UITableViewDataSource,UITableViewDelegate>
并设置代理:
self.rootV.tableView.delegate = self;
self.rootV.tableView.dataSource = self;
以及实现代理中必须实现的两个方法(上面已经描述过)
下属代码中的cell_id可以取其他的变量名,但是不同的cell,变量内容要不一样,否则重用的时候会有问题
static NSString *cell_id = @"cell_id_2";
static NSString *cell_id = @"cell_id";
注意:
当你由于自定义cell 而创建了一个类时(继承于UITableViewCell),在控制器中设置cell的内容时无论是label还是image都是使用你自己声明的属性,
如果使用系统的textLabel...那么对它的修改就不会影响你自定义的cell 也就不会显示在模拟器上(如果写代码期间遇到怎么修改也不显示的问题,看看是不是这个)
例如:labelName labelNumber等都是自己声明的属性
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
// id不同 cell里面的格式也不一样
static NSString *cell_id = @"cell_id_2";
SecondTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[SecondTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
cell.imageV.image = [UIImage imageNamed:self.dataArray[indexPath.row][@"image"]];
return cell;
}
static NSString *cell_id = @"cell_id";
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
// 字典的字面量写法
cell.imV.image = [UIImage imageNamed:self.dataArray[indexPath.row][@"image"]];
cell.labelName.text = self.dataArray[indexPath.row][@"name"];
cell.labelNumber.text = self.dataArray[indexPath.row][@"number"];
cell.labelPrice.text = self.dataArray[indexPath.row][@"price"];
return cell;
}
3.2 MVC:
1> M和V之间不直接通信,通过C控制器来负责两者之间的通信,
2> 创建model类的时候,一定要实现:- (void)setValue:(id)value forUndefinedKey:(NSString *)key 不然会崩
(一定要实现这个方法,防止数据中的key值在model的属性中找不到 而导致崩溃)
3> setValuesForKeysWithDictionary: 输入一个key-value的dictionary,调用setValue:forKey:进行一个一个的设置操作;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cell_id = @"cell_id";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
// 把数组中相应位置的model取出来,给cell的控件赋值。
PersonModel *model = self.arrayPerson[indexPath.row];
cell.textLabel.text = model.name;
cell.detailTextLabel.text = model.age;
return cell;
}
3.3 cell自适应高度:
1> 在自定义cell之后,在相对应的类中需要声明一个方法计算文字高度
在方法中需要用到如下的方法:
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context-------计算某段文本在限定的宽高内所占矩形的大小
这个方法会返回计算好高度之后的边框
注意方法中参数的对应类型:
// 这一步固定宽度 确定宽度之后才能计算高度
CGSize size = CGSizeMake([UIScreen mainScreen].bounds.size.width-100, 1000);
// 这个字体只是为了确认字体的大小 字体大小不同,结果不同
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:17]};
2> 这个自定义cell类完成之后,需要到控制器里修改自定义cell中控件的高度:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cell_id = @"cell_id";
ZSYTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[ZSYTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
cell.label.text = self.dataArray[indexPath.row];
// =========== 修改label高度 ============
// 不能直接将frame改变 间接改
CGRect rect = cell.label.frame;
// 返回是文字的高度
rect.size.height = [ZSYTableViewCell cellHeight:self.dataArray[indexPath.row]];
cell.label.frame = rect;
// =====================================
return cell;
}
通过plist文件显示:取plist文件里的东西 --> 添加信息
NSString *path = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"plist"];
self.dataArray = [NSMutableArray arrayWithContentsOfFile:path];