第一步: 将单元格中需要显示的内容设置成属性
MyTableView.m中:
/**
* 用来显示图片
*/
@property(nonatomic, retain) UIImageView *picture;
/**
* 用来显示姓名
*/
@property(nonatomic, retain) UILabel *nameLabel;
/**
* 用来显示性别
*/
@property(nonatomic, retain) UILabel *genderLabel;
/**
* 用来显示年龄
*/
@property(nonatomic,retain) UILabel *ageLabel;
/**
* 用来显示电话号码
*/
@property(nonatomic,retain) UILabel *phoneNumberLabel;
/**
* 用来显示爱好
*/
@property(nonatomic,retain) UILabel *hobbyLabel;
在该类的自定义方法中, 创建对应的属性对象, 只初始化和设置外观
例如:
#pragma mark 初始化方法
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
#warning 大坑: 如果在当前的初始化方法内, 想使用self.frame的时候, 取到的值不是自定义设定的值, 而是默认的width = 320 height = 44, origin.x = 0, origin.y = 0; 无论是什么型号的设备, 默认值都是这个
//初始化时还没有取到设定好的值, 而是使用默认值
// self.picture = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, self.frame.size.width * 0.3, self.frame.size.height - 20)];
self.picture = [[UIImageView alloc]init];
//设置frame在layoutSubview方法中
[self.contentView addSubview:self.picture];
self.picture.backgroundColor = [UIColor magentaColor];
[self.picture release];
self.nameLabel = [[UILabel alloc]init];
[self.contentView addSubview:self.nameLabel];
self.nameLabel.layer.masksToBounds = YES;
[self.nameLabel.layer setBorderWidth: 2];
[self.nameLabel.layer setCornerRadius:5];
[self.nameLabel.layer setBorderColor:[UIColor grayColor].CGColor];
[self.nameLabel release];
self.genderLabel = [[UILabel alloc]init];
[self.contentView addSubview:self.genderLabel];
// self.genderLabel.backgroundColor = [UIColor grayColor];
self.genderLabel.layer.masksToBounds = YES;
[self.genderLabel.layer setBorderWidth: 2];
[self.genderLabel.layer setCornerRadius:5];
[self.genderLabel.layer setBorderColor:[UIColor grayColor].CGColor];
[self.genderLabel release];
self.ageLabel = [[UILabel alloc]init];
[self.contentView addSubview:self.ageLabel];
self.ageLabel.layer.masksToBounds = YES;
[self.ageLabel.layer setBorderWidth: 2];
[self.ageLabel.layer setCornerRadius:5];
[self.ageLabel.layer setBorderColor:[UIColor grayColor].CGColor];
[self.ageLabel release];
self.phoneNumberLabel = [[UILabel alloc]init];
[self.contentView addSubview:self.phoneNumberLabel];
self.phoneNumberLabel.layer.masksToBounds = YES;
[self.phoneNumberLabel.layer setBorderWidth: 2];
[self.phoneNumberLabel.layer setCornerRadius:5];
[self.phoneNumberLabel.layer setBorderColor:[UIColor grayColor].CGColor];
[self.phoneNumberLabel release];
self.hobbyLabel = [[UILabel alloc]init];
// self.hobbyLabel.layer.masksToBounds = YES;
[self.hobbyLabel.layer setBorderWidth: 2];
[self.hobbyLabel.layer setCornerRadius:5];
[self.hobbyLabel.layer setBorderColor:[UIColor grayColor].CGColor];
#warning 注意: 如果想要当前Label自适应高度, 那么一定要设置显示任意行
self.hobbyLabel.numberOfLines = 0;
[self.contentView addSubview:self.hobbyLabel];
[self.hobbyLabel release];
}
return self;
}
/**
* 1. 当调用init方法时, 不触发.
2. 当调用addSubview时, 触发.
3. 当改变frame的时候, 并且当前frame与之前的不同时, 触发.
4. 当检测到屏幕旋转时, 触发
5. 当调用setNeedsLayout方法时, 触发
*/
-(void)layoutSubviews
{
#warning 切记: 调用父类的layoutSubViews
[super layoutSubviews];
//这里获得的self.frame为单元格的最新frame, (0, y, 320屏幕宽度, rowHeight)
self.picture.frame = CGRectMake(10, 10, self.frame.size.width * 0.4, self.frame.size.height - 20);
self.nameLabel.frame = CGRectMake(self.picture.frame.origin.x + self.picture.frame.size.width + 10, self.picture.frame.origin.y, self.frame.size.width - self.picture.frame.size.width - 30, self.picture.frame.size.height * 0.2);
self.genderLabel.frame = CGRectMake(self.nameLabel.frame.origin.x, self.nameLabel.frame.origin.y + self.nameLabel.frame.size.height + 10, self.nameLabel.frame.size.width * 0.4, self.nameLabel.frame.size.height);
self.ageLabel.frame = CGRectMake(self.nameLabel.frame.origin.x + self.genderLabel.frame.size.width + 10, self.nameLabel.frame.origin.y + self.nameLabel.frame.size.height + 10, self.nameLabel.frame.size.width - self.genderLabel.frame.size.width - 10, self.nameLabel.frame.size.height);
self.phoneNumberLabel.frame = CGRectMake(self.nameLabel.frame.origin.x, self.genderLabel.frame.origin.y + self.genderLabel.frame.size.height + 10, self.nameLabel.frame.size.width, self.nameLabel.frame.size.height);
//通过当前hobbyLabel要显示的文本, 来计算Label的高度
CGFloat hobbyHeight = [FirstTableViewCell heightOfSelfSuit:self.contact.hobby font:[UIFont systemFontOfSize:17] width:self.nameLabel.frame.size.width];
self.hobbyLabel.frame = CGRectMake(self.nameLabel.frame.origin.x, self.phoneNumberLabel.frame.origin.y + self.phoneNumberLabel.frame.size.height + 10, self.nameLabel.frame.size.width, hobbyHeight);
}
在爱好属性中, 文本长短不一, 如果将hobbyLabel的高度设定一个固定的值, 很可能导致显示不出所有信息,. 所以我们想要的效果是: 根据给出的文本长度, 来决定hobbyLabel的高度.
第二步: 定义一个方法, 用来返回改变后的高度, 将这个方法的返回值传给hobbyLabel.frame.size.height.
(声明为类方法的原因是: 这个方法只要是Label型变量就可以调用, 和cell无关, 只要传入正确的值就能有返回值, 写在任何一个类中都是可以的, 所以避免代码的复杂性, 定义为类方法, 免得还要定义一个对象来调用方法)
+(CGFloat)heightOfSelfSuit:(NSString *)text font:(UIFont *)font width:(CGFloat)width
{
//第一步: 设置文本显示的范围
//如果计算Label的自适应高度, 那么宽度需要固定, 高度需要设置为最大值, 不能起限制作用
CGSize size = CGSizeMake(width, MAXFLOAT);
//第二步: 设置要显示的文本样式
//在字典中存放
//NSFontAttributeName 系统给定的字体样式, 对高度不影响, 只有字体大小有影响
//font: 字体大小
NSDictionary *style = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
//第三步: 根据文本内容和文本样式计算Label的frame
/**
* 参数说明: 1.文本的显示范围
2.文本显示规则 usingFontLeading 根据字体大小来描绘字符串
3.文本样式: 通常只包括字体
4.上下文: nil
*/
CGRect result = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:style context:nil];
//返回自适应之后的高度
return result.size.height + 12;
}
第三步: 设定tableView的每个单元格高度的方法:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
#pragma mark cell自适应高度第一步
Contact *contact = self.contactArray[indexPath.section][indexPath.row];
//result是hobby文本框的高度
CGFloat result = [FirstTableViewCell heightOfSelfSuit:contact.hobby font:[UIFont systemFontOfSize:17] width:self.view.frame.size.width - 180];
#pragma mark 计算一行的高度
CGFloat singleHeight = [FirstTableViewCell heightOfSelfSuit:@"a" font:[UIFont systemFontOfSize:17] width:self.view.frame.size.width - 180];
//如果hobbyLabel只占一行时, 默认单元格高度为250
return 250 + result - singleHeight;
}