一、MVC,一种框架级的软件设计模式
(1)名称解释
"Model"数据模型封装了APP的数据
"View"视图 UIView以及它的子类,处理用户操作(大部分都是通过委托的方式交给控制器处理),显示数据
"Controll"控制器负责Model和View的通信,处理业务通信
(2)操作:分别建立三个分组:"Model、View、Controll"
(3)特点:
1.提高代码的复用性
2.提高代码的可读性
3."高内聚,低耦合",使功能更加模块化
二、自定义cell:(UITableViewCell)
1.新建model类,处理数据,处理成model对象
2.cell有的控件声明成自定义cell的属性,在cell的初始化方法中初始化属性,不设置frame
3.给cell添加model属性,重写setter方法,给控件赋值
4.再去重写layoutSubview方法,设置控件的frame
5.在协议方法中自定义cell,给cell的model属性赋值
1.新建model类(学生类),处理数据
2.cell初始化自身属性,自定义cell(MyView)
//初始化自身的同时初始化属性
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
//在创建的时候不知道行高
if (self) {
self.nameLabel = [[UILabel alloc]init];
self.nameLabel.textAlignment = NSTextAlignmentCenter;
self.nameLabel.backgroundColor = [UIColor yellowColor];
//不加在self上, cell自带contentView,方便开发者加控件(contenView高度比cell小0.5(分割线))
[self.contentView addSubview:self.nameLabel];
}
returnself;
}
3.给cell添加model属性,重写setter方法,给控件赋值
- (void)setStu:(Student *)stu{
_stu = stu;
self.nameLabel.text = stu.name;
self.ageLabel.text = [stu.age stringValue];
self.phoneNumberLabel.text = stu.phoneNumber;
self.sexLabel.text = stu.sex;
}
4.重写layoutSubview方法,设置控件的frame
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat width =self.bounds.size.width;
CGFloat height =self.bounds.size.height;
self.label.frame = CGRectMake(10,10, width -20, height -20);
}
5.在协议方法中自定义cell,给cell的model属性赋值
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reusepool"];
if (cell ==nil) {
cell = [[MyCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"reusepool"];
}
//注意这里是cell.label(自定义cell的属性)
cell.label.text =self.strArr[indexPath.row];
return cell;
}
三、tableView使用不同类型的cell:在返回cell的协议方法中,根据model对象属性的值判断使用哪种cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
Student *stu =self.stuArr[indexPath.row];
//根据本行显示的Model对象,判断使用哪种cell, 不同的重用池
if ([stu.sex isEqualToString:@"男"]) {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reusepool"];
if (cell == nil) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"reusepool"];
}
cell.stu = stu;
return cell;
}
else{
WomanCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuse"];
if (cell == nil) {
cell = [[WomanCustomCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"reuse"];
}
cell.stu = stu;
return cell;
}
}
四、cell自定义高度封装工具类
//在cell中定义一个label并在label中显示文本
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
//获取本行文本
NSString *str =self.strArr[indexPath.row];
//根据字符串算出完全显示需要多大
//参数1: CGSizeMake(345, 0)//label的宽度
//参数3: [UIFont systemFontOfSize:17]保证字体一致
//参数4: context上下文
//CGRect rect = [str boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil];
//可以将计算高度封装成一个工具类
CGFloat rectHeight = [CalculateHeight heightWithString:str labelWidth:tableView.bounds.size.width -30 font:17];
//计算cell应用的高度(label的宽高用self.contentView.bounds.size.height需要加0.5)
CGFloat height = rectHeight +20;//20是label与cell的大小差距
return height;
}