UITableViewCell高度自适应探索--UITableView+FDTemplateLayoutCell
地址: http://www.jianshu.com/p/7839e3a273a6
UITableViewCell高度自适应探索--cell预估高度(一)
地址: http://www.jianshu.com/p/6ab92579fcf1
UITableViewCell高度自适应探索--cell预估高度(二)
地址: http://www.jianshu.com/p/f3609cd9392e
今天,再提供一种AutoLayout与Frame相结合的方式来设置cell高度的方法.

今天这个方法的要点是:

  • 使用Autolayout在进行布局.
  • 使用Frame进行高度计算
  • 使用模型的属性缓存每个Cell第一次计算的高度.

相对于之前说的那些方法,这个方法比UITableView+FDTemplateLayoutCell使用起来更简单和容易理解(自从写FD那篇文章发表后收到很多网友的关于使用的问题,大部分是由于没有使用正确);并且克服了预估高度方式的那些问题,也不用把约束改来改去, 使计算的过程更加可控.

这种方法虽然是使用fram的方式计算,但是如果没有autoLayout,计算的过程就会复杂几倍,有时候可能还需要一个专门的类去管理子控件的frame.在我看来是一个比较不错的方法.

进入正题.

先看要实现的效果:

目标效果

其中文字的长度不一,图片可能有或没有.为了排除其他干扰,数据来自plist文件.

  • 这是我们自定义cell的设置,这些元素是固定的,我们使用AutoLayout对它们几个进行布局.

cell布局
  • 创建一个Message模型,赋予其对应的属性.
    由于cell的高度本质上还是基于模型数据来算的,所以计算高度的任务交给模型,故模型同时开放一个cellHeight的只读属性,将来好拿给控制器使用.
 @interface Message : NSObject

 // 头像、名字、和描述文字我给固定了,所以没有弄属性处理
@property (nonatomic, copy) NSString *imageName;
@property (nonatomic, copy) NSString *content;
@property (nonatomic, assign, readonly) CGFloat cellHeight; @end
  • 模型计算Cell高度,通过重写cellHeight的getter方法实现
 - (CGFloat)cellHeight {
if (!_cellHeight) {
CGFloat contentW = [UIScreen mainScreen].bounds.size.width - * margin; // 屏幕宽度减去左右间距
CGFloat contentH = [self.content boundingRectWithSize:CGSizeMake(contentW, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:contentFont]}
context:nil].size.height;
_cellHeight = contentLabelY + contentH + margin;
}
return _cellHeight;
}
注意:
上面高度的计算还没有将内容图片的高度计算在内.
并且实现了利用模型的cellHeight属性缓存第一次计算高度.
  • 由于内容图片不是每个cell都有,所以使用代码动态添加.
 // 属性声明
@property (strong, nonatomic) UIImageView *contentImageView;
// getter实现
- (UIImageView *)contentImageView {
if (!_contentImageView) {
_contentImageView = [[UIImageView alloc] init];
[self.contentView addSubview:_contentImageView];
}
return _contentImageView;
}
  • cell该接收模型了
 @property (nonatomic, strong) Message *message;
- (void)setMessage:(Message *)message {
_message = message;
self.contentLabel.text = _message.content;
if (message.imageName.length) {
self.contentImageView.hidden = NO;
self.contentImageView.image = [UIImage imageNamed:message.imageName];
}
else {
self.contentImageView.hidden = YES;
}
}

当然,这时候contentImageView当然是显示不出来的,因为我们还没有赠送它一个frame.那么它的frame从何而来呢?

一开始我们说过,计算要基于模型,所以接下来的思路是由模型算出imageView的frame,拿去给cell用.

回到模型cellHeight的getter方法,添加对imageName属性的处理:

 // 图片将要展示的frame作为模型的其中一个属性
@property (nonatomic, assign) CGRect contentImageFrame;
- (CGFloat)cellHeight {
if (!_cellHeight) {
CGFloat contentW = [UIScreen mainScreen].bounds.size.width - * margin; // 屏幕宽度减去左右间距
CGFloat contentH = [self.content boundingRectWithSize:CGSizeMake(contentW, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:contentFont]}
context:nil].size.height;
_cellHeight = contentLabelY + contentH + margin; // 对imageName属性的处理
if (self.imageName.length) {
UIImage *image = [UIImage imageNamed:self.imageName];
CGFloat imageH = image.size.height;
CGFloat imageW = image.size.width;
// 直接得出contentImageView应该显示的frame
_contentImageFrame = CGRectMake(margin, _cellHeight, imageW, imageH);
_cellHeight += imageH + margin;
}
}
return _cellHeight;
}
当上面代码执行完毕,contentImageFrame就有值了.接着,回到cell的setMessage:方法给contentImageView赋值.
 - (void)setMessage:(Message *)message {
_message = message;
self.contentLabel.text = _message.content;
if (message.imageName.length) {
self.contentImageView.hidden = NO;
self.contentImageView.image = [UIImage imageNamed:message.imageName];
// 给图片的frame赋值,这个值就是上面得到那个
self.contentImageView.frame = _message.contentImageFrame;
}
else {
self.contentImageView.hidden = YES;
}
}
  • 这时候使用起来就非常轻松了
 // 控制器tableView协议方法实现
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Message *message = self.dataList[indexPath.row];
return message.cellHeight;
}
完整代码下载:https://github.com/CoderAO/AutoCellHeightMix
 

UITableViewCell高度自适应探索--AutoLayout结合Frame的更多相关文章

  1. UITableViewCell高度自适应的关键点

    iOS开发中对于UITableViewCell高度自适应的文章已经很多很多,但如果cell内容比较复杂,刚使用autolayout配置自使用时还是总不能一次性成功. KEY POINT 这里只说设置的 ...

  2. uitableviewcell高度自适应笔记

    今天看了几篇uitableviewcell高度自适应的文章,大体分为两种方式. 第一种方式,cell里面有label,在cellforrow绘制的时候计算Label的可能高度,并且在此时重新计算cel ...

  3. UITableViewCell 高度自适应

    UITableViewCell 高度自适应一直是我们做动态Cell高度时遇到的最烦躁的问题,Cell动态高度计算可以去看看sunny的这篇文章介绍,今天主要和大家分享下我在使用systemLayout ...

  4. 原生的UITableViewCell高度自适应,textLabel自动换行显示

    /* * 设置子项cell **/ - (UITableViewCell *)getChildCell:(UITableView *)tableView and:(NSIndexPath *)inde ...

  5. 第二篇、为UITableViewCell 高度自适应加速 缓存cell的高度

    通过NSCache缓存已经算好的行高 @interface ZHCellHeightCalculator : NSObject //系统计算高度后缓存进cache -(void)setHeight:( ...

  6. autolayout 高度自适应

    https://lvwenhan.com/ios/449.html #import "ViewController.h" #import "MyTableViewCell ...

  7. UITableViewCell 高度计算从混沌初始到天地交泰

    [原创]UITableViewCell 高度计算从混沌初始到天地交泰 本文主要基予iOS UITableViewCell 高度自适应计算问题展开陈述,废话少说直入正题: UITableView控件可能 ...

  8. iframe框架自适应高度 uncanght SecurityError: Blocked a frame with origin "null" from accessing a frame ....

    来源于crm项目的contact/edit.html 一.背景是这样的 最近在做crm系统的前端页面,有一个页面呢,点击“查看全部信息”时会弹出,这个弹窗里面又有分页导航,分页不是使用ajax 异步刷 ...

  9. SnapKit swift实现高度自适应的新浪微博布局

    SnapKit swift版的自动布局框架,第一次使用感觉还不错. SnapKit是一个优秀的第三方自适应布局库,它可以让iOS.OS X应用更简单地实现自动布局(Auto Layout).GtiHu ...

随机推荐

  1. [Hive - LanguageManual] Hive Concurrency Model (待)

    Hive Concurrency Model Hive Concurrency Model Use Cases Turn Off Concurrency Debugging Configuration ...

  2. 介绍Google App Engine

    Google App Engine是一个网络应用托管服务(web application hosting service).所谓网络应用(By web application),我们的意思的可以通过网 ...

  3. 取消本地SVN文件夹与服务器关联

    问题:之前建了一个SVN代码库,同步了代码上去,但中途发现建库时的规则搞错了,就把服务器上的库给删了重建,然后改变本地代码的svn服务器关联地址,但使用Relocate一直报错. 错误有两种情况:1. ...

  4. gdb 技巧

    现实数组: 比如说要显示a[10]中全部的内容用 p a显示的是地址,用p *a显示的是第一个元素显示全部或某一个:p (int [10])*a或者p *a@10 如果你使用 p *a@3 或 p * ...

  5. 第二百五十天 how can I 坚持

    html排版,好烦心. 我以为我会哭,但是我没有.---<领悟> 确实是搞不懂自己,到底想要什么?弟弟最近也不知道咋的了,感觉有点不对劲呢. 最近雾霾好严重,希望我们的后代不会知道雾霾是什 ...

  6. CalendarUtil

    package ch.makery.address.util; import java.text.ParseException; import java.text.SimpleDateFormat; ...

  7. 搭建nodejs环境推荐用两个工具:nvm和npm

    nvm 是 nodejs version manager 的简称,即:nodejs版本管理npm 是 nodejs package manager 的简称,即:nodejs模块管理 有了这两个工具,管 ...

  8. java中MessageDigest加密工具类

    import java.security.MessageDigest; public class EncryptionKit { public static String md5Encrypt(Str ...

  9. MD5验证工具:md5sum

    linux 下 shell命令 ,制作md5码 也用于软件的md5校验     MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.MD5 全称是报文摘要算法(Message-Digest ...

  10. Win7关机出现关闭程序提示框

    运行输入Gpedit.msc回车打开组策略,在左侧选计算机配置/管理模板/系统/关机选项,在右侧双击“关闭会阻止或取消关机的应用程序的自动终止功能”,在打开的提示框中选“已启用”,按确定即可.