第十二章 UITableViewCell的自定义
一、自定义Cell
自定义cell的步骤:
1.创建一个类继承于UITableViewCell
2.实现UITableViewCell的初始化方法:
- (instancetype)initWithStyle:(UITableViewCellStyle*)style reuseIdentifier:(NSString*)reuseIdentifier;
3.确保所有的你想添加的子视图都在自定义cell的初始化方法中创建,由于UITableView的重用机制,一个cell在第一次创建成功并用于下一次显示的时候,不会再走初始化方法,这样可以避免子视图的重复创建
4.在cell的子视图创建成功后,将子视图设置为属性,类似于UITableViewCell所自带的textLabel和detailLabel属性。便于在UITableView的协议中给定义视图赋值
二、Model类型对象的使用
Model类:主要是为了给我们提供数据,简单而言即自定义类且继承于NSObject的称之为Model。而继承于UIView的称之为View类。OC中的KVC就是帮助我们将字典转换为Model类而存在的
1.设置cell被选中时的样式:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UITableViewCellSelectionStyleBlue
UITableViewCellSelectionStyleGray
UITableViewCellSelectionStyleDefault
2.设置文本内容的折行显示
第一步:获取要计算高度的内容
NSString* str = self.dataArray[indexPath.row / 2];
第二步:计算文字的高度,计算出来文字的矩形范围
CGRect rect = [str boundingRectWithSize:(CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 30, MAXFLOAT)) options:(NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin ) attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0]} context:nil];
参数解释:
Size:为文字给定一个最大范围
options:设置计算内容大小的方式
LineFragmentOrigin:将每一行文字都按照矩形来计算,用来计算印刷体文字的大小
FontLeading:计算一行文字大小的时候要将行间距计算在内
attributes:文字的属性,例如文字的字体、或者是文字的大小
第三步:返回内容的高度:内容的高度 + 上留白 + 下留白。当我们的文字中如果有emoji表情时,列如😁,他会比平常文字稍微高一点点,我们为了更精确,多加个2;
return rect.size.height + 10 + 10 + 2;
3.如果当前视图控制器的父类是tableView,那么self.view == self.tableView,注册----self.view 和self.tableView 在类中是指的同一个东西,只是返回值类型不同,没有层级关系
4.cell的自适应高度的步骤
1.在tableView返回行高的代理方法中得到需要计算高度的内容,通过字符串对象的bounding。。。。。计算出来内容的矩形大小,通过矩形大小得到高度。内容的高度+不变的高度。这就是cell的行高
2.在自定义cell的label的懒加载中,根据cell的行高重新计算label的高度(cell的高度-除去该label以外的高度)
注意:如果要自适应高度,一定记得要将行数设置为0;_contentLabel.numberOfLines = 0;
自适应高度,本质上就是根据内容的高度修改cell的高度
例:
//懒加载
- (UILabel*)contentLabel{
if (!_contentLabel) {
_contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, CGRectGetWidth([UIScreen mainScreen].bounds) - 30, 30)];
//如果要自适应高度,一定记得要将行数设置为0;
_contentLabel.numberOfLines = 0;
_contentLabel.backgroundColor = [UIColor greenColor];
[self addSubview:_contentLabel];
}
//当我们将cell加入到重用池中的时候,系统不会帮我们进行任何操作,会将cell原样放入重用池
//cell在复用的时候,不会改任何东西,只是重新赋值
//当我们每次执行该方法的时候,说明我们为label的text赋值了。说明我们正在使用Label,有可能有新的内容进来,需要重新计算label的高度
//点的语言体系不一样,不能连用
CGRect rect = _contentLabel.frame;
if ((self.frame.size.height - 20) != rect.size.height) {
rect.size.height = self.frame.size.height - 20;
_contentLabel.frame = rect;
}
return _contentLabel;
}
5.宏定义:实质上就是整体替换,记得加括号
1.名称必须全部大写 如果想要正常命名 kImage_�Width
2.举例:
1.#define IMAGE_WIDTH ((CGRectGetWidth([UIScreen mainScreen].bounds) - 80 )/3)
2.#define kImage_Width ((CGRectGetWidth([UIScreen mainScreen].bounds) - 80 )/3)
6.一般将cell中的控件通过懒加载进行控件的初始化
好处:
1.将初始化方法中大部分代码拆分开了。便于我们后期维护
2.当我们需要用到那个控件的时候,我们调用该控件的懒加载方法,这个时候才会进行初始化;用不到就不用调用,就不会初始化,节省了内存空间
3.cell一共有三部分组成:左侧的ImageVeiw 中间的contentView 右侧的辅助视图accessoryView 这三者都是通过懒加载进行初始化操作,所以我们不调用getter方法,对应的控件就不会初始化,就不会显示