课题一:如何计算Cell高度

方案一:直接法(面向对象)

想知道妹纸爱你有多深?直接去问妹纸本人吧!

嗯!Cell也是一样的,想知道cell到底有多高?直接问Cell本人就好了。直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值。

  • 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内容多少自动调整

    第一步 - 添加好约束.gif
  • 第二步:再给这个Cell添加点别的东东,就叫这个东东BottomCub了。为Cub添加好约束。

    第二步 - 随便添加点什么.gif
  • 第三步:为这个Cell写一个返回Cell高度 - 也就是BottomCub最大Y值的方法

#import "TestCell.h"

@interface TestCell ()
@property (strong, nonatomic) IBOutlet UILabel *longLabel;
@property (strong, nonatomic) IBOutlet UIView *bottomCub;
@end @implementation TestCell // Cell的构造方法
+ (instancetype)creatWithTitle :(NSString *)title inTableView :(UITableView *)tableView
{
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(self)];
if (!cell) {
cell = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:kNilOptions].lastObject;
}
cell.longLabel.text = title;
return cell;
} /**
* 拿到bottomCub的最大Y值并返回
*/
- (CGFloat)cellHeight
{
[self layoutIfNeeded]; // 一定要强制布局下,否则拿到的高度不准确
return CGRectGetMaxY(self.bottomCub.frame);
} @end
  • 第四步:在代理方法中设置Cell高度
    *注意:计算Cell高度的过程,一定不要放在heightForRow代理方法中!这一点在后文中将会有所提及。
#import "AskCellViewController.h"
#import "TestCell.h" @interface AskCellViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (strong, nonatomic) UITableView *tableView; /** 测试数据 - Cell中文字内容数组*/
@property(copy,nonatomic) NSArray *testTitleArray; @end @implementation AskCellViewController - (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView]; self.tableView.frame = self.view.bounds;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableFooterView = [[UIView alloc] init];
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell *cell = [TestCell creatWithTitle:self.testTitleArray[indexPath.row] inTableView:tableView];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// *注意:计算Cell高度的过程,一定不要放在此代理方法中!这一点在后文中将会有所提及,此处仅为演示方便
CGFloat cellHeight = [[TestCell creatWithTitle:self.testTitleArray[indexPath.row] inTableView:tableView] cellHeight];
NSLog(@"%f",cellHeight);
return cellHeight;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.testTitleArray.count;
}
#pragma mark - Lazy
- (UITableView *)tableView
{
if (!_tableView) {
_tableView = [[UITableView alloc] init];
}
return _tableView;
} - (NSArray *)testTitleArray
{
return @[@"我是第一个Cell",@"我是第二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二个Cell",@"我是第三个Cell"];
} @end
  • 效果

    动态设定Cell高度结果.gif

方案二:自己算(面向过程)

想知道妹纸爱你有多深?自己来算算看~

通常情况下,Cell之所以不等高,是因为Cell内部文字区域的高度会根据文字数量动态变化,图片区域的高度会根据图片数量而自动变化。也就是说,只要知道文字区域的高度、图片区域的高度,就可以硬生生计算出Cell的高度了。

  • 第一步:硬生生的将每个Cell的高度算出来,并保存在一个数组中
  • 第二步:heightForRow方法中返回相应的CellHeight
#import "CalculatorViewController.h"
#import "TestCell.h" @interface CalculatorViewController ()<UITableViewDelegate,UITableViewDataSource> @property (strong, nonatomic) UITableView *tableView;
/** 测试数据 - Cell中文字内容数组*/
@property(copy,nonatomic) NSArray *testTitleArray;
/** 用来存Cell高度的数组*/
@property(copy,nonatomic) NSArray *cellHeightArray; @end @implementation CalculatorViewController - (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView]; self.tableView.frame = self.view.bounds;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableFooterView = [[UIView alloc] init];
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell *cell = [TestCell creatWithTitle:self.testTitleArray[indexPath.row] inTableView:tableView];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat cellHeight = [self.cellHeightArray[indexPath.row] floatValue];
return cellHeight;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.testTitleArray.count;
}
#pragma mark - Lazy
- (UITableView *)tableView
{
if (!_tableView) {
_tableView = [[UITableView alloc] init];
}
return _tableView;
}
- (NSArray *)testTitleArray
{
return @[@"我是第一个Cell",@"我是第二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二二个Cell",@"我是第三个Cell"];
}
- (NSArray *)cellHeightArray
{
NSMutableArray *cellHeightTMPArray = [@[] mutableCopy];
// 开始硬生生的计算每一个Cell高度
for (NSString *string in self.testTitleArray) {
CGFloat cellHeight = 0;
// 一个Cell由两部分组成 - 高度自动调整的Label & bottomCub
// bottomCub高度是确定的 - 120,Label和bottomCub之间的间距是确定的 - 8
static CGFloat bottomCubHeight = 120;
static CGFloat bottomMargin = 8;
// 计算Label的高度 - 其实就是计算Lable中的String的总高度
// 1. 拿到将要放入Lable的String
NSString *stringForLabel = string;
// 2. 根据文字内容、字体(固定值)、文字区域最大宽度计算String总高度
static CGFloat fontSize = 17;
CGFloat labelHeight = [stringForLabel sizeWithFont:[UIFont systemFontOfSize:fontSize] constrainedToSize:CGSizeMake(self.tableView.frame.size.width, CGFLOAT_MAX)].height;
// 3. 拿到了总高度,放入数组
cellHeight = labelHeight + bottomMargin + bottomCubHeight; [cellHeightTMPArray addObject:@(cellHeight)];
}
return cellHeightTMPArray;
}
@end
  • 效果
    ummmm就不给效果图了哦,和上一张是一样一样的~

方案三:利用iOS8新特性

想知道妹纸爱你有多深?知道这个干嘛,直接通过iOS8,让妹纸爱上你不就好啦~

其实,iOS8已经提供了直接通过XIB让Cell高度自适应的方法了,只要简单拖拖线,根本木有必要计算Cell高度,就可以搞定不等高Cell

  • 第一步:设置tableView的估算Cell高度&rowHeight值为自动计算模式
- (void)viewDidLoad {
[super viewDidLoad]; self.tableView.estimatedRowHeight = 100; // 随便设个不那么离谱的值
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  • 第二步:为Cell中最下面的View设置约束 - 除了要定高、定宽、左上角粘着Label外,还要设置bottom距contentView的bottom间距为固定值,如0

bottomCub约束的添加方式.gif
  • 第三步:一定要注意 - 不能实现heightForRow代理方法!!!不能实现heightForRow代理方法!!!不能实现heightForRow代理方法!!!重要的事情说三遍...
    - (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath
    {
    return 1000;

    iOS8新特性实现Cell高度的自适应.gif
  • 效果:一样杠杠滴~

课题二:在哪计算Cell高度

方案一:在heightForRow代理方法中计算

  • 示例代码:见课题一方案一
  • 说明:在这里进行计算是非常糟糕的选择,因为系统调用heightForRow方法非常频繁 感兴趣的小伙伴可以打印测试下...在这里进行计算,意味着系统每调用一次heightForRow方法,就会执行一次高度计算...好可怕有木有

    处理不等高TableViewCell的更多相关文章

    1. iOS之处理不等高TableViewCell的几种方法

      课题一:如何计算Cell高度 方案一:直接法(面向对象) 直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值. 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内 ...

    2. 自定义不等高cell—storyBoard或xib自定义不等高cell

      1.iOS8之后利用storyBoard或者xib自定义不等高cell: 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView(cell的content ...

    3. iOS-UI控件之UITableView(三)- 自定义不等高的cell

      Storyboard_不等高 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView之间的间距约束 设置tableViewCell的真实行高和估算行高 / ...

    4. flexbox实现不等宽不等高的瀑布流布局

      第一次做不等宽不等高的瀑布流布局,刚开始企图用ccs3的column属性+flexbox来实现,瞎捣鼓半天都没有能弄好, 弱鸡哭晕在厕所(┬_┬),气的午饭都没有吃. 后来逼着自己冷静下来,又捣鼓了1 ...

    5. iOS开发——UI进阶篇(三)自定义不等高cell,如何拿到cell的行高,自动计算cell高度,(有配图,无配图)微博案例

      一.纯代码自定义不等高cell 废话不多说,直接来看下面这个例子先来看下微博的最终效果 首先创建一个继承UITableViewController的控制器@interface ViewControll ...

    6. wpf ListBox,item两列不等高。

      业务有这样的需求,类似瀑布流.内容两列不等高展示. 只需要继承panel,重写MeasureOverride和ArrangeOverride方法就行了. 很简单,内容都在代码里. using Syst ...

    7. 不等高cell的tableView界面搭建

      一.搭建界面 1.界面分析 分析界面的层次结构,分析界面应该用什么控件来搭建 2.界面层次结构 分析之后,我们可以把这个界面分为四个模块(topView middleView commentView ...

    8. iOS-UI控件之UITableView(二)- 自定义不等高的cell

      不等高的cell 给模型增加frame数据 所有子控件的frame cell的高度 @interface XMGStatus : NSObject /**** 文字\图片数据 ****/ // ... ...

    9. input 与 button 的问题 (空隙/不等高/对不齐)及 解决办法

      1. input 与 button 为什么有空隙? - 要明白为什么,需要了解一下几点基础知识(耐心看完,你会发现竟如此简单)     1. input 与 button 都属于行级块元素,都具有文本 ...

    随机推荐

    1. CSS layout入门

      元素与盒 在HTML中常常使用的概念是元素,而在CSS中,布局的基本单位是盒,盒总是矩形的. 元素与盒并非一一对应的关系,一个元素可能生成多个盒,CSS规则中的伪元素也可能生成盒,display属性为 ...

    2. jQuery语法总结及注意事项

      1.关于页面元素的引用通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom ...

    3. .NET通用基本权限系统

      DEMO下载地址: http://download.csdn.net/detail/shecixiong/5372895 一.开发技术:B/S(.NET C# ) 1.Windows XP以上 (支援 ...

    4. rxjs5.X系列 —— Combination/Multicasting系列 api 笔记

      欢迎指导与讨论 :) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第三篇 -- Combination组合与Multicasting广播.如有错漏,希望大家指出提醒O ...

    5. C#基础知识回顾-- 反射(3)

      C#基础知识回顾-- 反射(3)   获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺垫, ...

    6. 手把手教你入门mac idea

      一.前沿 去年入职后, 公司有很多人使用的是idea , 而不是eclipse. 之前就想转向idea, 但一直没转过来~~原因是团队的人提倡用开源eclipse.现在下定决心转向idea. 虽然, ...

    7. 动网论坛password暴力破解程序代码

      <%  response.buffer=false  '为防止程序陷入死循环,初始化一些最大重试值  Dim MaxPassLen,MaxPassAsc  MaxPassLen=20 'pass ...

    8. 辛星浅谈PHP的混乱的编码风格

      我们都知道.各种编程语言都有自己的风格,即使是像C和C++那样一脉相承的语言(C++本意全然兼容C的语法).编程风格上还是有些区别.比方非常典型的就是C++风格的单行凝视和C风格的多行凝视. 而尽管J ...

    9. Android开发环境中的概念和工具介绍

      最近学习Android开发,以前使用C/C++多一些,现在再补点Java知识,不管是哪种语言,都不过是一种工具而已,真的学起来,大同小异,无谓优劣.学习Android编程肯定是要先从环境搭建开始,无论 ...

    10. 【jQuery插件】用jQuery Masonry快速构建一个pinterest网站布局(转)

      [jQuery插件]用jQuery Masonry快速构建一个pinterest网站布局 时间:2011年03月21日作者:愚人码头查看次数:29,744 views评论次数:25条评论 前段时间领导 ...