关于UITableViewCell的大小随文本大小自动调整的问题

本文介绍了在iOS7中如何动态调整UITableViewCell的高度以适应文本内容。主要方法是使用boundingRectWithSize替代了弃用的sizeWithFont系列方法,通过计算NSAttributedString的属性字典来预估文本大小。在UITableView中,通过代理方法`tableView:heightForRowAtIndexPath:`来设置cell高度,但可能会导致重复计算。为了优化,建议将高度计算方法封装到自定义的UITableViewCell类中,并考虑是否能减少重复计算的高度设置过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      1、根据文本大小动态调整UILabel大小:

       iOS 7之前有一系列的方法可以计算NSString绘制后的具体大小,然后以此预估控件的大小,从而可以根据文本长短动态调整控件大小。一共5个方法,都是NSString的方法,都以sizeWithFont开头,通过传入字体格式、换行模式、预设大小等来计算绘制后的大小。iOS7开始禁用了这些方法,使用

  CGSize size = [str boundingRectWithSize:CGSizeMake(200, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingTruncatesLastVisibleLine attributes:attriDic context:nil].size;

来代替。这里是使用了一个方法来整个了之前的所有方法,但是提供的参数是类似的,不过这里的attributes:attriDic部分使用的是和NSAttributedString同样的属性字典,即NSAttributedString有很多属性可以调节,而这里使用同样的属性调节key,基本可以满足所有的文本属性设置了。使用方法是使用这些特定的key构建一个字典,如:

NSDictionary * attriDic = @{NSFontAttributeName : [UIFont systemFontOfSize:15],NSParagraphStyleAttributeName : style};

这里的NSFontAttributeName 是字体对应的key,NSParagraphStyleAttributeName 是NSMutableParagraphStyle 类对象对应的类,这个类使用来管理段落格式的,行距就是有它调节。

 

  2、使用上述方法可以很好的做到预估字符串显示的大小,从而相应的更改承载这些字符串的控件大小,比如UILabel。但是这个东西碰到UITableViewCell就有个难点:比如cell上面要显示文本,但是这个文本是不确定的,会根据数据的变化而变化,那么可能这个文本的显示会是1行、两行或者3、4行更多,而显示这个文本的cell也需要跟着变换高度,因为不同的行数,高度不一样。貌似这里只要调节cell的大小就可以了,但是对于UITableView,调节cell的高度是需要通过委托方法来实现的,就是方法:

-(CGFloat )tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

一般使用tableView,显示的数据都是结构相同的,也一般保存在数组里面,所以这里有一个参数indexPath,通过这个多以对应的获取每一条数据,然后通过每个特定的数据来确定当前这个indexPath的cell的高度。所以这里需要根据数据,计算一遍cell的高度。

然后在cell的构建的委托方法:

-(UITableViewCell* )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

里面cell构建,cell上面显示文本的控件肯定也需要根据数据计算一遍,所以这里还要算一遍。


好像难点也没有什么,就是要通过计算字符串绘制后的大小设置cell的高度。

不过有两点问题:1、如果cell是自定义的类,那么我觉得可以把

-(CGFloat )tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

这里面需要计算cell高度的方法写在自定义的cell里面,这样的封装性比较好。因为cell的高度,虽然是根据传入的数据不断改变的,但是根本的还是cell本身的控件排版决定的,这件事不应该是viewcontroller的责任,而是cell的一个属性,所以把事情归结给cell会更好。比如你现在的tableview需要混入另一种cell,那么高度计算只需要调用另一个cell的同一个方法。

   然后这里又不需要cell的对象本身的属性,因为这就是一个计算的过程,所以可以写成类方法,这样不用构建cell的实例就可以计算cell的高度,这样避免了不必要的内存消耗。

   

 2、即使封装好了,不过这里还是有些浪费,因为高度计算其实做了两次。因为UITableView的cell的高度有专门的方法,这里需要计算。然后我们的cell的构建,肯定是要计算里面空间的大小。不知道是否有更好的方法我还没有发现,不过我的想法是,如果在

-(UITableViewCell* )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

也就是cell的构建方法里面可以给cell设定大小,然后系统也会读取就好了,那么就只要计算一次就可以了。实际是直接设置cell的frame是没用了。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值