IOSday08 自定义等高和不等高cell
自定义等高cell
frame自定义
-
新建一个继承自UITableViewCell`的子类
@interface XMGTgCell : UITableViewCell
- 在
XMGTgCell.m
文件中 - 重写
-initWithStyle:reuseIdentifier:
方法 - 在这个方法中添加所有需要显示的子控件
- 给子控件做一些初始化设置(设置字体、文字颜色等)
- 不能和系统自带的属性名相同
- 在这个方法中添加所有的子控件
- 在
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
return self;
}
- 重写
-layoutSubviews
方法- 一定要调用
[super layoutSubviews]
- 在这个方法中计算和设置所有子控件的frame
- 在这个方法中计算所有子控件的frame
- 一定要调用
- (void)layoutSubviews
{
[super layoutSubviews];
// ......
}
在XMGTgCell.h文件中提供一个模型属性,比如XMGTg模型
@class XMGTg;
@interface XMGTgCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) XMGTg *tg;
@end
在XMGTgCell.m中重写模型属性的set方法
- 在set方法中给子控件设置模型数据
- (void)setTg:(XMGTg *)tg
{
_tg = tg;
// .......
}
在控制器中
- 注册cell的类型
[self.tableView registerClass:[XMGTgCell class] forCellReuseIdentifier:ID];
- 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 访问缓存池
XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 设置数据(传递模型数据)
cell.tg = self.tgs[indexPath.row];
return cell;
}
Autolayout自定义
- 新建一个继承自
UITableViewCell
的子类 - 新建一个xib文件(文件名最好跟类名一致)
- 修改cell的class为指定类型
![](/Users/yangzh/Desktop/课堂笔记 /images/Snip20150629_245.png)
- 绑定循环利用标识
![](/Users/yangzh/Desktop/课堂笔记 /images/Snip20150629_246.png)
- 添加子控件,设置子控件约束
![](/Users/yangzh/Desktop/课堂笔记 /images/Snip20150629_251.png)
将子控件连线到类扩展中
---
@interface XMGTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;
@end
在XMGTgCell.h文件中提供一个模型属性,比如XMGTg模型
@class XMGTg;
@interface XMGTgCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) XMGTg *tg;
@end
```
在XMGTgCell.m中重写模型属性的set方法
- 在set方法中给子控件设置模型数据
- (void)setTg:(XMGTg *)tg
{
_tg = tg;
// .......
}
在控制器中
-
注册xib文件
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGTgCell class]) bundle:nil] forCellReuseIdentifier:ID];
-
给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 访问缓存池
XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 设置数据(传递模型数据)
cell.tg = self.tgs[indexPath.row];
return cell;
}
storybork
步骤与xib相似不同之处在于不要注册可以自动加载storybork上的cell
在控制器中
- 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"tg";
// 访问缓存池
XMGTgCell *cell = [tableView
dequeueReusableCellWithIdentifier:ID];
// 设置数据(传递模型数据)
cell.tg = self.tgs[indexPath.row];
return cell;
}
纯代码自定义不等高的cell
给模型增加frame数据
- 所有子控件的frame
- cell的高度
计算文字尺寸
CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT);
NSDictionary *textAttrs = @{NSFontAttributeName : [UIFont systemFontOfSize:14]};
CGFloat textH = [self.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textAttrs context:nil].size.height;
@interface XMGStatus : NSObject
/** 头像的frame */
@property (nonatomic, assign) CGRect iconFrame;
/** cell的高度 */
@property (nonatomic, assign) CGFloat cellHeight;
@end
- 重写模型cellHeight属性的get方法
- (CGFloat)cellHeight
{
if (_cellHeight == 0) {
// ... 计算所有子控件的frame、cell的高度
}
return _cellHeight;
}
在控制器中
- 实现一个返回cell高度的代理方法
- 在这个方法中返回indexPath位置对应cell的高度
- 返回每一行cell的具体高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
XMGStatus *status = self.statuses[indexPath.row];
return status.cellHeight;
}
- 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"tg";
// 访问缓存池
XMGStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 设置数据(传递模型数据)
cell.status = self.statuses[indexPath.row];
return cell;
}
storybork自定义等高cell(iOS8开始才支持)
- 添加子控件和contentView之间的间距约束
![](/Users/yangzh/Desktop/课堂笔记 /images/Snip20150701_88.png)
-
设置tableViewCell的真实行高和估算行高
- 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算)
self.tableView.rowHeight = UITableViewAutomaticDimension;
- 告诉tableView所有cell的估算高度
self.tableView.estimatedRowHeight = 44;
如果要支持iOS8之前
- 如果cell内部有自动换行的label,需要设置preferredMaxLayoutWidth属性
- (void)awakeFromNib
{
// 手动设置文字的最大宽度(目的是:让label知道自己文字的最大宽度,进而能 够计算出自己的frame)
self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
- 设置tableView的cell估算高度
告诉tableView所有cell的估算高度(设置了估算高度,就可以减少tableView:heightForRowAtIndexPath:方法的调用次数)
self.tableView.estimatedRowHeight = 200;
在代理方法中计算cell的高度
XMGStatusCell *cell;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
// 创建一个cell(cell的作用:根据模型数据布局所有的子控件,进而计算出cell 的高度)
if (!cell) {
cell = [tableView dequeueReusableCellWithIdentifier:ID];
}
// 设置模型数据
cell.status = self.statuses[indexPath.row];
return cell.height;
}
- (CGFloat)height
{
// 强制布局cell内部的所有子控件(label根据文字多少计算出自己最真实的尺寸)
[self layoutIfNeeded];
// 计算cell的高度
if (self.status.picture) {
return CGRectGetMaxY(self.pictureImageView.frame) + 10;
} else {
return CGRectGetMaxY(self.text_label.frame) + 10;
}
}
Google、百度
- 解决燃眉之需
stackoverflow(全英文, IT问答网站)
- 不能用中文关键词
- 开发中遇到的问题,在这里基本都有答案
翻转头文件
苹果官方文档
- UI相关:CocoaTouch Layer -> UIKit -> Guides
- 关注WWDC会议视频(学习新东西)
多关注别人的博客\微博
- 简书