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. google proto buffer安装和简单示例

    1.安装 下载google proto buff. 解压下载的包,并且阅读README.txt,根据里面的指引进行安装. $ ./configure $ make $ make check $ mak ...

  2. F5 刷新功能

    //1.引入单元 uses ShlObj; //2.执行命令 procedure TForm1.Button1Click(Sender: TObject); begin SHChangeNotify( ...

  3. Gradle – Spring 4 MVC Hello World Example – Annotation

    In this tutorial, we will take the previous Gradle + Spring MVC XML example, rewrite it to support @ ...

  4. POJ 3660 Cow Contest (Floyd)

    http://poj.org/problem?id=3660 题目大意:n头牛两两比赛经过m场比赛后能判断名次的有几头可转 化为路径问题,用Floyd将能够到达的路径标记为1,如果一个点能 够到达剩余 ...

  5. Linux使用locate命令定位文件

    FIND命令 很多Linux用户喜欢使用find命令来查找文件,例如他们通常喜欢这样做: find / -name 'pattern' 确实find的强大功能不仅仅用来查找文件,它能用来定位更加细节的 ...

  6. Educational Codeforces Round 1(D. Igor In the Museum) (BFS+离线访问)

    题目链接:http://codeforces.com/problemset/problem/598/D 题意是 给你一张行为n宽为m的图 k个询问点 ,求每个寻问点所在的封闭的一个上下左右连接的块所能 ...

  7. JavaScript随笔记(一)基础概念以及变量类型

    一.JavaScript中的基础概念 1.defer属性 一般我们在引用外部js文件的时候往往是将引用文件的位置放在标签当中,比如那么在标签中引入多个js文件时,浏览器会按照引入顺序加载执行这些引入的 ...

  8. 简谈HTML5与APP技术应用

    HTML5到底能给企业带来些什么? HTML5是近年来互联网行业的热门词汇,火的很.微软IE产品总经理发文: 未来的网络属于HTML5.乔布斯生前也在公开信<Flash之我见>中预言:像H ...

  9. 自己学会汉化DevExpress控件[转]

    1. 文档导读 本文档以颜色区分内容的重要性和不同性,阅读本文档时请注意以下事项: 1. 红色部分表示需要注意的重点内容:(加粗的尤甚) 2. 蓝色部分表示相应于前版本新增的内容: 3. 紫色部分表示 ...

  10. c# Internet时间服务器同步

    2009-02-02 17:48 8226人阅读 评论(2) 收藏 举报 服务器internetc#socketstringwindows 需要用到的名空间 using System.Net; usi ...