办法被总计cell的惊人,利用storyboard自定义不等于高cell

这里运用heightForRowAtIndexPath:方法总计不对等高cell的莫大,在用这么些情势此前要明确是方法的调用时间跟调用次数:

我们在齐一致首《经过代码自定义不顶高cell》中修了tableView的系文化,本文将当上文的根底及,利用storyboard对自定义不抵高cell部分做相应的改。
同上文一样,利用storyboard自定义不抵高cell,视图有本拿凡根本,控制器和模型有的转移无是老挺。为了保险逻辑上的明明白白,咱们要论上文的作文顺序,分模块逐一讲解。
如故以老习惯,新建一个工,来到ViewController.h文件,让ViewController继承自UITableViewController,来到Main.storyboard,删除View
Controller控制器,拖一个UITableViewController,勾选”Is Initial View
Controller”,绑定类名为ViewController。至此,准备工作基本好了,现在起首分模块教学。
一、Model
具体操作步骤及《通过代码自定义不等于高cell》一样,这里不举行更。
二、Controller
坐改变了创cell的法门,所以控制器部分的代码和《经代码自定义不抵高cell》有些不等同,我在此一贯给闹详细操作。
俺们到控制器部分,先讲明一个屡次组,用于拍卖模型数据:
// 用来加载来自statuses.plist文件中之字典数据,并且以那多少个更换为对应之模子
然后存储起来@property(strong,nonatomic)NSArray*statusArr;
导入MJExtension框架,包含MJExtension和ESStatus的腔文件,然后重新写statusArr的getter方法:

  • 1.于reloadData时,有多少条数,就相会调用多少次是措施(比如一共来80长长的数,就会调用80次等是方法)
  • 2.于暴发cell出现不时,就会调用一差是点子
- (NSArray*)statusArr {// 使用MJExtension框架if(!_statusArr) {// 将字典转为模型_statusArr = [ESStatus mj_objectArrayWithFilename:@"statuses.plist"];    }return_statusArr;}

咱俩在达标一致篇《经过代码自定义不顶高cell》中读了tableView的连锁知识,本文将以上文的底子及,利用storyboard对从定义不顶高cell部分做相应的改动。
与上文一样,利用storyboard自定义不顶高cell,视图有以拿凡重要,控制器和模型有的改动无是特别要命。为了保证逻辑上之一清二楚,我们或按照上文的做顺序,分模块逐一讲解。
抑或按老习惯,新建一个工,来到ViewController.h文件,让ViewController继承自UITableViewController,来到Main.storyboard,删除View
Controller控制器,拖一个UITableViewController,勾选”Is Initial View
Controller”,绑定类名为ViewController。至此,准备工作主题完成了,现在起先分模块教学。
一、Model
具体操作步骤和《因此代码自定义不对等高cell》一样,这里不开还。
二、Controller
以改变了创cell的计,所以控制器部分的代码和《经代码自定义不顶高cell》有些不等同,我于此间一直为起详细操作。
大家过来控制器部分,先讲明一个往往组,用于拍卖模型数据:
// 用来加载来自statuses.plist文件中的字典数据,并且用这易为对应之型
然后存储起来@property(strong,nonatomic)NSArray*statusArr;
导入MJExtension框架,包含MJExtension和ESStatus的腔文件,然后再度写statusArr的getter方法:

//返回cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return cellHeight;
}
- (NSArray*)statusArr {// 使用MJExtension框架if(!_statusArr) {// 将字典转为模型_statusArr = [ESStatus mj_objectArrayWithFilename:@"statuses.plist"];    }return_statusArr;}

实现数据源协议的- tableView:
numberOfRowsInSection:方法,重回tableView中cell的行数。
// 返回tableView中cell行数-
(NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {returnself.statusArr.count;//
statusArr数组中元素的个数就是tableView中cell的行数}

  • 用以描述cell的xib

新建一个继往开来自UITableViewCell的ESStatusCell的接近,来到Main.storyboard,展开View
Controller Scene,选中Table View
Cell,将这Class更改为ESStatusCell,如图所示

xib.png

澳门金冠开户 1

算算不等于高cell低度的首先种植方法:估计中度

  • 1.每当viewDidLoad方法中设置cell的臆度低度

(void)viewDidLoad {
    [super viewDidLoad];
    //设置估算高度
    self.tableView.estimatedRowHeight = 170;
}
  • 2.于heightForRowAtIndexPath:方法被总括cell的万丈

//定义间距
#define WYLMargin 10
//返回cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //获取对应的模型
    WYLTopicItem *item = self.topicItemArray[indexPath.row];

    //定义cell的高度
    CGFloat cellHeight = 0;

    //图片+间距
    cellHeight += WYLMargin + 35 + WYLMargin;

    //label的高度
    CGSize textMaxSize = CGSizeMake([UIScreen mainScreen].bounds.size.width - 2 * WYLMargin, MAXFLOAT);
    CGFloat labelHeight = [item.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height;
    cellHeight += labelHeight + WYLMargin;

    //底部导航栏的高度
    cellHeight += 35 + WYLMargin;
    NSLog(@"heightForRowAtIndexPath-----%zd",indexPath.row);

    return cellHeight;
}
  • 3.采取量低度总结cell中度的长处和缺陷
  • 优点:
    1.减小heightForRowAtIndexPath方法的调用次数
    2.得给小看无显示的cell的低度延迟总结
  • 缺点:
    1.tableView之contentSize不太规范
    2.以tableView滑动过程中,滚动条之长会变来变去,可能会面来跳跃效果
    3.cell自缓存池中加载时同时会见另行总计其的可观

绑定类名.png
累点击Xcode右上较量的”Show the Attributes Inspector”,更改Table View
Cell的Style为Custom,给Identifier绑定可拔取标识符”status”。注意,这多少个只是选拔标识符可随便写,不过相对不要同网重要字还,因为稍后尾还要因而到。具体操作如下:

计不齐高cell低度的次种植办法:定义字典保存cell中度

  • 1.概念存储cell低度的字典

/** 存储cell高度的字典*/
@property (nonatomic ,strong) NSMutableDictionary *cellHeightDict;
/** 懒加载存储cell高度的字典*/
-(NSMutableDictionary *)cellHeightDict
{
    if (_cellHeightDict == nil) {
        _cellHeightDict = [NSMutableDictionary dictionary];
    }

    return _cellHeightDict;
}
  • 2.每当heightForRowAtIndexPath:方法被总计cell的惊人

//返回cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //获取对应的模型
    WYLTopicItem *item = self.topicItemArray[indexPath.row];

    //用模型的地址作为字典的key
    NSString *key = [NSString stringWithFormat:@"%p",item];

    //取出模型对应的cell的高度
    CGFloat cellHeight = [self.cellHeightDict[key] doubleValue];

    //如果cellHeight有值,就是cell的高度已经计算过了,直接返回
    if (cellHeight) return cellHeight;

    //如果cell的高度没有计算过,就计算cell高度
    //图片+间距
    cellHeight += WYLMargin + 35 + WYLMargin;

    //label的高度
    CGSize textMaxSize = CGSizeMake([UIScreen mainScreen].bounds.size.width - 2 * WYLMargin, MAXFLOAT);
    CGFloat labelHeight = [item.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height;
    cellHeight += labelHeight + WYLMargin;

    //底部导航栏的高度
    cellHeight += 35 + WYLMargin;

    //将计算过的cell高度保存到字典中
    self.cellHeightDict[key] = @(cellHeight);
    NSLog(@"heightForRowAtIndexPath----%zd",indexPath.row);

    return cellHeight;
}
  • 3.行使字典保存cell低度的利弊
  • 优点:
    当cell重新加载到tableView中的当儿,不会面再总括cell的惊人
  • 缺点:
    代码太过繁琐

澳门金冠开户 2

算算不对等高cell低度的老二种植方法:在范中定义cellHeight属性

  • 1.当模型.h文件被益cellHeight属性

#import <Foundation/Foundation.h>
@interface WYLTopicItem : NSObject
/** 根据当前模型数据计算出来的cell高度*/
@property (nonatomic ,assign) NSInteger cellHeight;
@end
  • 2.每当模型.m文件被贯彻cellHeight的getter方法

#import "WYLTopicItem.h"
@implementation WYLTopicItem
-(NSInteger)cellHeight
{
    //如果cellHeight已经计算过,就直接返回
    if (_cellHeight) return _cellHeight;

    //图片+间距
    _cellHeight += WYLMargin + 35 + WYLMargin;

    //label的高度
    CGSize textMaxSize = CGSizeMake([UIScreen mainScreen].bounds.size.width - 2 * WYLMargin, MAXFLOAT);
    CGFloat labelHeight = [self.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height;
    _cellHeight += labelHeight + WYLMargin;

    //底部导航栏的高度
    _cellHeight += 35 + WYLMargin;

    return _cellHeight;
}
@end

-3.于heightForRowAtIndexPath:方法吃统计cell的中度

//返回cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //获取对应的模型
    WYLTopicItem *item = self.topicItemArray[indexPath.row];
    return item.cellHeight;
}

效果图.png

绑定cell循环利用标识符.png
涵盖ESStatusCell的腔文件,实现数据源协议的- tableView:
cellForRowAtIndexPath:方法:
// 返回tableView中的cell-
(UITableViewCell)tableView:–(UITableView)tableView
cellForRowAtIndexPath:(NSIndexPath)indexPath {//
1.树可选择标识符staticNSString
ID =@”status”;//
那些标识符一定要跟眼前Xcode中绑定的一致// 2.
依照可接纳标识符去缓存池中取出可用之cellESStatusCell *cell =
[tableView dequeueReusableCellWithIdentifier:ID];//
3.将statusArr中之范传递给视图中的模型属性cell.status=self.statusArr[indexPath.row];//
因cell的行号取出模型数据returncell;}

时至前日,控制器部分的代码暂时先告一段落,大家先行去动手定视图部分。
三、View
来storyboard,展开View Controller
Scene,选中status(也即使是tableView的cell),将Prototype
Cell拖死一些,方便于内拖子控件。先拖入一个UIImageView控件,然后点击Xcode右下角的Pin,弹出Add
New Constraints界面,去丢Constrain to
margins前边的逗,让UIImageView顶部和左边距离其大控件的离也10,设置UIImageView的雄厚和赛分别吗30(一般景色下,大多数控件需要4长框才可以确定该职务以及尺寸,不过为起例外,像UILabel只要暴发半点单框就可以)。注意,对诺约束规范的虚线变为红色的实线,以及安装Width和Height前面打上勾才表示约束成功。然后点击Update
Frames前边的列表,选中Items of New Constraints,最后点击Add 4
Constraints完成对UIImageView的自律。具体操作如下图:

澳门金冠开户 3

封锁用户头像部分
有关通过storyboard来成功对控件的AutoLayout约束,一般都相比较简单,网上发出诸多连锁的课程,这里不开展开。遵照操作步骤,我们更来布局剩下的道岔控件:

澳门金冠开户 4

律了事后大概是此样子
发必要提一下,在布局了知乎正文子控件的时段,一定毫无忘记了点击Xcode右上斗的”Show
the Attributes
Inspector”,设置Label的Lines属性值为0,以确保博客园正文文字在必要之早晚做到换行。接下来,相当重大的如出一辙步,就是给就布局完成子控件连线:

澳门金冠开户 5

深受cell上之分段控件连线
于前边几篇稿子被,我们说了,视图有一般是多个步骤:创造子控件、给子控件设置岗位和尺寸,以及让个子控件传递模型数据。完成连线,前边两独步骤就是成功了,现在即便给子控件设置数据:

// 给子控件传递模型数据- (void)setStatus:(ESStatus *)status {    _status = status;self.iconImageView.image= [UIImageimageNamed:status.icon];// 给用户头像控件传递对应模型self.nameLabel.text= status.name;// 给用户昵称控件传递对应模型// 设置VIP图标if(status.isVip) {// 如果是VIP用户self.vipImageView.hidden=NO;// 显示用户VIP标识self.vipImageView.image= [UIImageimageNamed:@"vip"];// 设置VIP用的身份标识self.nameLabel.textColor= [UIColororangeColor];// VIP用户昵称用橙色标识}else{// 如果不是VIP用户self.vipImageView.hidden=YES;// 隐藏VIP用户标识self.nameLabel.textColor= [UIColorblackColor];// 非VIP用户昵称用黑色标识}self.text_label.text= status.text;// 给用户微博文本控件传递模型数据// 用户微博内容是否包含图片if(status.picture) {// 如果用户微博内容中包含图片self.pictureImageView.hidden=NO;// 显示用户微博内容图片控件self.pictureImageView.image= [UIImageimageNamed:status.picture];// 设置用户微博正文配图}else{// 如果用户微博内容不包含图片self.pictureImageView.hidden=YES;// 隐藏用户微博内容图片控件}}

咱俩运行程序看一下:

澳门金冠开户 6

次遵照预期运行
自从程序运行结果来拘禁,UI界面的着力框架已形成了,剩下的饶是指向cell的万丈举行微调。
四、调整cell的高度
同经代码创设于定义cell不一致,那反过来不需要我们手动去统计cell的万丈了,只待对系代码和封锁做相应的调就好了。
率先来到控制器文件,在-
viewDidLoad方法被安tableView的rowHeight属性为UITableViewAutomaticDimension,然后设置tableView的estimatedRowHeight为随意大于0的常量:

- (void)viewDidLoad {    [superviewDidLoad];self.tableView.rowHeight=UITableViewAutomaticDimension;// 表示cell高度自动计算,其中UITableViewAutomaticDimension是一个常量self.tableView.estimatedRowHeight=44;// 设置cell的估算高度,一般只要是大于0的常量就可以,但是习惯上设置它为系统默认的cell高度}

方两桩设置号称是苹果之Self-Sizing
Cells技术,功用很强,不过遗憾的是,它就帮忙iOS 8未来的型,对于iOS
7就无法了。但是,在随档蒙,它还不足以解决我们的问题。当然,这不是这项技术分外,首假如咱种被之和讯配图控件在兴风作浪。
盖网易配图控件有时候显示,有时候不显得,所以我们应有对该开特殊处理。来到storyboard,展开今日头条配图控件下边的Constraints约束,选中中度自律,往ESStatusCell.m文件被拖线,如下图所示:

澳门金冠开户 7

以到果壳网配图控件中度的约
本,光将到新浪配图控件的低度约还不够。因为新浪正文控件与乐乎配图控件之间暴发10区间的封锁,而博客园配图控件又跟父控件之间来10的间隔,所以,当网易配图控件隐藏时,这有限独10底区间有一个须要随着隐藏。大家以到和讯配图控件与父控件之间距离为10之这漫长框:

澳门金冠开户 8

将到乐乎配图控件与父控件之间的封锁
咱将到地点那有限单控件未来,当网易配图控件需要隐藏时,大家用其常量设置为0。当用体现网易配图控件时,大家更过来该常量的价值:

// 用户微博内容是否包含图片if(status.picture) {// 如果用户微博内容中包含图片self.pictureImageView.hidden=NO;// 显示用户微博内容图片控件self.pictureImageView.image= [UIImageimageNamed:status.picture];// 设置用户微博正文配图self.pictureHeight.constant=100;// 如果微博有配图,则恢复其高度为100self.pictureBottom.constant=10;// 如果微博有配图,则恢复其底部与父控件之间的距离为10}else{// 如果用户微博内容不包含图片self.pictureImageView.hidden=YES;// 隐藏用户微博内容图片控件self.pictureHeight.constant=0;// 如果微博没有配图,则将其高度设置为0self.pictureBottom.constant=0;// 如果微博没有配图,则设置其底部与父控件之间的距离为0}

运行程序瞅一观察:

澳门金冠开户 9

宏观运行.gif
简直是周!O(∩_∩)O~。为了证实点所说的Self-Sizing
Cells技术成效强大,大家可以这一个收回掉,然后再次来运转品种看一下:

澳门金冠开户 10

废除电动总计代码以后的运转效果.gif
收回后,程序的功效这就更换挫了。与通过代码自定义不对等高cell比起来,用storyboard完成同样的法力是未是概括好多了?可是,前面早已说罢,这种技能只好动用在iOS
8及其未来的系统,假如假设适配iOS
7怎么处置吧?作为依靠总责的好青年,下面就开形成iOS 8从前的系统适配。
五、适配iOS 8在此之前的网
第一来到storyboard,删除天涯论坛配图控件底部同父控件之间的那根约束。由于我们前以到了这根本约束,所以于去在此之前先选着其,然后右击,删除其跟pictureBottom之间的连线关系:

澳门金冠开户 11

Snip20160821_86.png
除去该约束和pictureBottom属性之间的连线关系下,可径直以这么些从Constraints中去除了:

澳门金冠开户 12

删除新浪配图控件底部同父控件之间的约束.jpg
随后,删除天涯论坛配图控件的莫大自律和pictureHeight属性之间的连线关系(与方不同,这一次约束不可能去):

澳门金冠开户 13

删除网易配图控件的中度约和pictureHeight属性之间的连线关系
零星束缚与两属性之间的连线关系还尚未了,这两属性也便一向不因而了。来到ESStatusCell.m文件,直接以那些删除:

澳门金冠开户 14

剔除多余的特性
结余的性能为尚无了,那么和该属性有关的代码也就从未有过由此了,直接去解决系统报错:

澳门金冠开户 15

剔除没因而底代码.png
我们以达标一样首著作被提过,与tableView的cell中度相关的,除了rowHeight属性之外,也固然只剩余-tableView:heightForRowAtIndexPath:代理方了。来到控制器,实现该法:

#pragma mark -// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {return250;// 250是一个比较吉利的数字,在这里可以帮你解决程序报错}

若果总结cell子控件的莫大,就不可能不靠模型,在回去cell低度的措施吃实现:

// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度ESStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];// 这里也要用到可重用标识符,建议将- tableView: cellForRowAtIndexPath:方法中声明可重用标识符的代码拿到外面去cell.status=self.statusArr[indexPath.row];

算cell的可观。假如起博客园配图,大家特需要以到新浪配图控件的最好丰富y值,然后加上彼底部同父控件之间10间距就得;倘诺没有知乎配图,我们只有需要将到和讯文本控件,然后使用该极其深y值长10间隔就会总计出cell的冲天。然而,我们在此之前将控件的性讲明在ESStatusCell的切近增加中,从控制器中凡不可以访问的,为那,我们须将其拿到其的峰文件中错过。也就是说,现在举观望图头文件化这样:

#import@classESStatus;@interfaceESStatusCell:UITableViewCell/** 用于接收来自控制器传入的模型数据 */@property(strong,nonatomic) ESStatus *status;// 模型属性// 用户头像@property(weak,nonatomic)IBOutletUIImageView*iconImageView;// 不要与tableView的imageView属性冲突// 用户昵称@property(weak,nonatomic)IBOutletUILabel*nameLabel;// 用户的VIP标识@property(weak,nonatomic)IBOutletUIImageView*vipImageView;// 用户发送的微博文字内容@property(weak,nonatomic)IBOutletUILabel*text_label;// 不要与tableView的textLabel属性冲突// 用户发送的微博配图@property(weak,nonatomic)IBOutletUIImageView*pictureImageView;@end

咱俩更回去控制器中失去,在-
tableView:heightForRowAtIndexPath:方法吃总计相关子控件的最好老低度,然后拿cell低度重返:

// 计算cell的高度CGFloatcellHeight =0;// 初始化cellHeight的值if(cell.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(cell.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(cell.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;

辩论及讲,至此,大家的行事算完了了,然而,我们先运行程序看一下:

澳门金冠开户 16

欲调试版.gif
于结果上看,那多少个并不曾达标我们预料的效果,有些地点距离很可怜,而略地点,新浪正文文字有显得不都。这是什么由吧?想转,大家算cell高度的代码,实际上是冲pictureImageView和text_label这一点儿单控件遵照约束规范了显示出来之后这前提条件的。可实际上,在我们统计cell中度的上,这有限个控件并不曾依照相应的律原则了体现出来。由此,大家所统计的cell中度的值,并无纯粹。
视图中的分控件要先行吸收到数,然后才能够按照对应的束缚规范总计出科学的frame,而子控件被的数额是通过-
tableView:
cellForRowAtIndexPath:那些艺术传递过来的。此外,我们统计cell低度的代码是以-
tableView:heightForRowAtIndexPath:那些法子被开展的。为了求证问题,我们事先来经打印,查看转应声有限个措施的调用顺序:

澳门金冠开户 17

区区独方法的调用顺序
起打印结果来拘禁,- tableView:heightForRowAtIndexPath:那个措施的调用要于-
tableView:
cellForRowAtIndexPath:那个艺术早。也就是说,子控件还没接收到数,并且,在爆发多少的根基及,依照提前装的格原则,总结好子控件的frame,咱们不怕曾于-
tableView:heightForRowAtIndexPath:这么些法中拿cell的惊人算寿终正寝了,这样结果本来不对了!为者,我们必须想办法,要于盘算cell低度的代码在此之前,让cell内部的分支控件按照约束原则提前总结同一整个。解决的点子是强制刷新一下:
// 强制刷新[cell layoutIfNeeded];
来拘禁一下胁迫刷新之后的结果:

澳门金冠开户 18

强制刷新.gif
强制刷新后,效果是好过多了,不过文字控件部分如故来问题。原因与方一样,仍旧因文字控件最老幅面统计后矣。我们以胁制刷新代码此前,先手动总括文字控件的绝酷开间:
// 总计文字控件的极端要命开间cell.text_label.preferredMaxLayoutWidth=
[UIScreenmainScreen].bounds.size.width-20;

还看一下程序运行的职能:

澳门金冠开户 19

中度总计截至毕.gif
六、性能优化
透过前的攻,大家知晓-
tableView:heightForRowAtIndexPath:这些办法调用异常频繁,出于程序性能方面的考虑,我们尚需对这做相应的优化工作。
1、优化- tableView:heightForRowAtIndexPath:方法中之cell
俺们为此要在-
tableView:heightForRowAtIndexPath:方法吃创设cell,目标是为临时被其传递数据,能提前总结其内部子控件的frame。在代码优化往日,大家先来打印一下夫艺术被所创立cell的内存地址:

澳门金冠开户 20

系统创立了多cell
起打印出来的cell内存地址,以及右侧的直拖动条能,咱们创造了老大多之cell。其实并未这么些必要,我们只有待创立一个cell,然后给它赋值不同的数量就是可了。所以,我们应当用成立cell的代码变成全局变量:

ESStatusCell *cell;// 声明一个全局变量#pragma mark -
// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {if(cell ==nil) {// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    cell.status=self.statusArr[indexPath.row];// 计算文字控件的最大宽度cell.text_label.preferredMaxLayoutWidth= [UIScreenmainScreen].bounds.size.width-20;// 强制刷新[cell layoutIfNeeded];// 计算cell的高度CGFloatcellHeight =0;if(cell.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(cell.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(cell.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;}

俺们还来打印一下cell的内存地址:

澳门金冠开户 21

骨子里只暴发一致客cell
虽仍旧打印了许多,但是打内存地址来拘禁,其实这么些cell都是暨一个,这样就是直达了一个性质优化的目的。
2、优化- tableView:heightForRowAtIndexPath:方法
自此前面的打印结果来拘禁,-
tableView:heightForRowAtIndexPath:方法调用相当之频繁,每个cell都至少要调用一赖,有些cell甚至会频调用。那么,为啥而调用这么累也?这一个还得起tableView的contentSize说从。
我们且精晓,苹果做作业是大厚用户体验的。在此以前方的动图我们会望,每一趟tableView现身后,屏幕右侧会出去一个直的滚动条,用户可通过这滚动条大约了解后还有小数量。而屏幕及滚条之长而跟tableView的contentSize有关。频繁的调用-
tableView:heightForRowAtIndexPath:方法,其目的就是为了设置tableView的contentSize。
那般做,用户体验看起是是,然而,当tableView有许多分组,且每组又生出好多流行,那么是形式的调用频率将是甚可观之。有时候一个App打开之后,屏幕会预先出现白屏,然后重新加载tableView的数据,或多或少是以那一个原因。苹果也发现及了是题目,所未来来即出了机动揣度技术。
自动揣摸技术既可以保证App加载时受tableView设置合适的contentSize,又会解决程序性能问题。接下来大家用钻一下机关揣摸技术。
咱当本文中提到了,在设置tableView的estimatedRowHeight属性的价值平常,只要大于0就好,其实是价的装也是生必然技术的。经常状态下,大家会为这特性赋值44,因为系统的cell默认低度就是44。不过,作为本项目而言,我们了好拿其的值设大一些。
我们事先经打印了然一下,在未设置estimatedRowHeight属性值时之情况:

澳门金冠开户 22

勿设置estimatedRowHeight属性的值的前.png
从今结果高达看,打印是怪之多。大家又来拘禁一下,将estimatedRowHeight属性的价设置也44事后的图景:

澳门金冠开户 23

只有9条数据
起打印结果来拘禁,打印显著减小了,只生9长达。我们再来拘禁一下,将estimatedRowHeight属性的值设置也100随后的景:

澳门金冠开户 24

打印结果更是缩减及7漫漫数据.png
打印结果再度少了,只发7久数。我们再来拘禁一下,将estimatedRowHeight属性的价设置也200之后的气象:

澳门金冠开户 25

打印结果但发5漫长.png
咱看来,打印结果只留5条了。我们重新来拘禁一下,将estimatedRowHeight属性的值设置也1000自此的状:

澳门金冠开户 26

打印结果如故5长条.png
自于是这样执着于打印,并无是为自己是打印狂魔,更无是为凑篇幅,而是为注明问题。没有发现,我老是上打印截图的时候,都把控制器屏幕一起截在内?其实,这么些estimatedRowHeight属性的价值是与我们的屏幕低度,以及tableView下边cell的莫过于中度有关的!
自因而之模拟器是HUAWEI6s,它的屏幕低度为667,而屏幕及现能观察底cell数量正是5独。大家先是糟设置estimatedRowHeight属性的值是44,667
/ 44 =
15.1,理论及道,应该会打印16长长的新闻,不过坐大家的tableView总共只发9长cell,因而唯有打印9漫长音讯。第二不行我们装estimatedRowHeight属性的值也100后,屏幕打印出7修音信,是坐667
/ 100 =
6.67,所以打印7久信息。可是,只要我们estimatedRowHeight属性的价值超出667 /
5 =
133.4后头,控制台打印出的信永远都止来5长条,这是以我们我们屏幕上本展现的刚巧是5漫长。
经地方的分析,我们得汲取这样一个定论:澳门金冠开户,合理之设置estimatedRowHeight属性的价值,可以使得压缩-
tableView:heightForRowAtIndexPath:方法的调用次数,从而达成优化程序性能的目标。可是,这些属于性值的高低与屏幕低度,以及cell的实在低度相关,既无是更为小更好,也未是尤为丰盛更加好。

除开可以经过tableView的estimatedRowHeight性实现自动推断技术外,还可兑现代理的
tableView: estimatedHeightForRowAtIndexPath:
术及平的目标。
3、优化总结cell中度的设计方案
咱俩的代码还有此外一个问题。回忆一下大家事先所模拟到之知,就是一个控件内部私有的性,最好是声称在看似扩张中,不要暴露于外围。可是,大家于上头总括cell中度时,恰恰违背了此法。为了能以控制器中以到视图内部的连锁控件,我们用ESStatusCell的私房属性移到了ESStatusCell.h文件被,这样做是勿安全之。为这,我们亟须想一个计,在既不背规划条件的情事下,又能叫外界抱cell的真正低度。
缓解案是,把总结cell真实低度的这有些代码封装于ESStatusCell这多少个类似里,然后再以计结果回到,以供外界调用。具体操作是,在ESStatusCell.h文件被表明一个cellHeight属性,然后在ESStatusCell.m文件中还写cellHeight的getter方法,最终,控制器可以经过看cell的cellHeight属性获取相应的结果。
故此,ESStatusCell.h文件最终的代码应该是:

#import@classESStatus;@interfaceESStatusCell:UITableViewCell/** 用于接收来自控制器传入的模型数据 */@property(strong,nonatomic) ESStatus *status;// 模型属性// 提供计算cell高度的借口@property(assign,nonatomic)CGFloatcellHeight;@end

重写cellHeight的getter方法:

// 返回cell的高度。因为- tableView:heightForRowAtIndexPath:方法的关系,这个调用也很频繁- (CGFloat)cellHeight {// 计算文字控件的最大宽度// self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;// 强制刷新[selflayoutIfNeeded];// 计算cell的高度CGFloatcellHeight =0;if(self.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(self.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(self.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;}

然则只要注意,因为- tableView:heightForRowAtIndexPath:方法的关联,-
cellHeight那些主意的调用也蛮频繁,而计量网易文本控件的最好可怜开间只有待算同一不佳,所以可以设想用该放在-
awakeFromNib方法中尽:

- (void)awakeFromNib {// 计算文字控件的最大宽度self.text_label.preferredMaxLayoutWidth= [UIScreenmainScreen].bounds.size.width-20;}
  • tableView:heightForRowAtIndexPath:方法在外头通过访cell的cellHeight属性,获取cell的忠实中度:

ESStatusCell *cell;#pragma mark -// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {if(cell ==nil) {// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    cell.status=self.statusArr[indexPath.row];returncell.cellHeight;// 返回cell的高度}

原文链接:http://www.jianshu.com/p/35f5b68bbe4a
兑现数据源协议的- tableView:
numberOfRowsInSection:方法,重临tableView中cell的行数。
// 返回tableView中cell行数-
(NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {returnself.statusArr.count;//
statusArr数组中元素的个数就是tableView中cell的行数}

新建一个延续自UITableViewCell的ESStatusCell的近乎,来到Main.storyboard,展开View
Controller Scene,选中Table View
Cell,将其Class更改为ESStatusCell,如图所示

澳门金冠开户 27

绑定类名.png
持续点击Xcode右上比的”Show the Attributes Inspector”,更改Table View
Cell的Style为Custom,给Identifier绑定可采取标识符”status”。注意,这么些只是拔取标识符可随便写,但是相对不要与系统要字还,因为稍后尾还要用到。具体操作如下:

澳门金冠开户 28

绑定cell循环利用标识符.png
饱含ESStatusCell的条文件,实现数据源协议的- tableView:
cellForRowAtIndexPath:方法:

// 返回tableView中的cell- (UITableViewCell*)tableView:--(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {// 1.确立可重用标识符staticNSString*ID =@"status";// 这个标识符一定要与前面Xcode中绑定的一致// 2. 根据可重用标识符去缓存池中取出可用的cellESStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];// 3.将statusArr中的模型传递给视图中的模型属性cell.status=self.statusArr[indexPath.row];// 根据cell的行号取出模型数据returncell;}

迄今,控制器部分的代码暂时先告一段落,大家先行去出手定视图部分。
三、View
过来storyboard,展开View Controller
Scene,选中status(也即是tableView的cell),将Prototype
Cell拖死一些,方便于里拖子控件。先拖入一个UIImageView控件,然后点击Xcode右下角的Pin,弹出Add
New Constraints界面,去丢Constrain to
margins前边的逗,让UIImageView顶部和左距离该大控件的去为10,设置UIImageView的富足和大分别吗30(一般景色下,大多数控件需要4修框才会确定这职与尺寸,不过也有不同,像UILabel只要出三三两五个框就足以)。注意,对诺约束规范的虚线变为黄色的实线,以及安装Width和Height前边打上勾才表示约束成功。然后点击Update
Frames前面的列表,选中Items of New Constraints,最终点击Add 4
Constraints完成对UIImageView的格。具体操作如下图:

澳门金冠开户 29

自律用户头像部分
至于通过storyboard来就对控件的AutoLayout约束,一般都对比简单,网上有多息息相关的教程,这里不做展开。依据操作步骤,我们重来布局剩下的子控件:

澳门金冠开户 30

封锁了之后大概是其一法
暴发必不可少提一下,在布局了新浪正文子控件的当儿,一定毫无忘记了点击Xcode右上比的”Show
the Attributes
Inspector”,设置Label的Lines属性值为0,以保微博正文文字以必要之上做到换行。接下来,相当重大的相同步,就是叫就布局完成子控件连线:

澳门金冠开户 31

被cell上的子控件连线
在头里几首著作被,咱们说罢,视图有一般是三单步骤:创立子控件、给子控件设置岗位与尺寸,以及让个子控件传递模型数据。完成连线,前边两独步骤就是完了,现在即令给子控件设置数据:

// 给子控件传递模型数据- (void)setStatus:(ESStatus *)status {    _status = status;self.iconImageView.image= [UIImageimageNamed:status.icon];// 给用户头像控件传递对应模型self.nameLabel.text= status.name;// 给用户昵称控件传递对应模型// 设置VIP图标if(status.isVip) {// 如果是VIP用户self.vipImageView.hidden=NO;// 显示用户VIP标识self.vipImageView.image= [UIImageimageNamed:@"vip"];// 设置VIP用的身份标识self.nameLabel.textColor= [UIColororangeColor];// VIP用户昵称用橙色标识}else{// 如果不是VIP用户self.vipImageView.hidden=YES;// 隐藏VIP用户标识self.nameLabel.textColor= [UIColorblackColor];// 非VIP用户昵称用黑色标识}self.text_label.text= status.text;// 给用户微博文本控件传递模型数据// 用户微博内容是否包含图片if(status.picture) {// 如果用户微博内容中包含图片self.pictureImageView.hidden=NO;// 显示用户微博内容图片控件self.pictureImageView.image= [UIImageimageNamed:status.picture];// 设置用户微博正文配图}else{// 如果用户微博内容不包含图片self.pictureImageView.hidden=YES;// 隐藏用户微博内容图片控件}}

俺们运行程序看一下:

澳门金冠开户 32

先后依据预期运行
自打程序运行结果来拘禁,UI界面的为主框架都就了,剩下的虽是针对性cell的冲天举办微调。
四、调整cell的高度
暨经过代码创造于定义cell不相同,这拨不需大家手动去算cell的可观了,只需要针对有关代码和自律做相应的调整就好了。
第一到控制器文件,在-
viewDidLoad方法吃安tableView的rowHeight属性为UITableViewAutomaticDimension,然后设置tableView的estimatedRowHeight为擅自大于0底常量:

- (void)viewDidLoad {    [superviewDidLoad];self.tableView.rowHeight=UITableViewAutomaticDimension;// 表示cell高度自动计算,其中UITableViewAutomaticDimension是一个常量self.tableView.estimatedRowHeight=44;// 设置cell的估算高度,一般只要是大于0的常量就可以,但是习惯上设置它为系统默认的cell高度}

方两宗设置号称是苹果的Self-Sizing
Cells技术,效率非常有力,不过遗憾之是,它才辅助iOS 8将来的体系,对于iOS
7就无法了。可是,在仍项目中,它还不足以解决大家的题材。当然,这不是这项技能好,重假如大家种遭到之天涯论坛配图控件在作怪。
坐博客园配图控件有时候突显,有时候不亮,所以大家该本着那些举办特别处理。来到storyboard,展开果壳网配图控件下面的Constraints约束,选中中度约,往ESStatusCell.m文件被拖线,如下图所示:

澳门金冠开户 33

用到知乎配图控件中度的律
当然,光用到今日头条配图控件的冲天自律还不够。因为果壳网正文控件与果壳网配图控件之间发生10距离的约,而天涯论坛配图控件又跟父控件之间有10底区间,所以,当乐乎配图控件隐藏时,那简单单10之距离有一个得随着隐藏。我们用到乐乎配图控件与父控件之间距离为10之这长长的框:

澳门金冠开户 34

用到知乎配图控件与父控件之间的约
咱用到面就有限只控件将来,当网易配图控件需要隐藏时,我们将该常量设置为0。当用显示天涯论坛配图控件时,大家再回复该常量的值:

// 用户微博内容是否包含图片if(status.picture) {// 如果用户微博内容中包含图片self.pictureImageView.hidden=NO;// 显示用户微博内容图片控件self.pictureImageView.image= [UIImageimageNamed:status.picture];// 设置用户微博正文配图self.pictureHeight.constant=100;// 如果微博有配图,则恢复其高度为100self.pictureBottom.constant=10;// 如果微博有配图,则恢复其底部与父控件之间的距离为10}else{// 如果用户微博内容不包含图片self.pictureImageView.hidden=YES;// 隐藏用户微博内容图片控件self.pictureHeight.constant=0;// 如果微博没有配图,则将其高度设置为0self.pictureBottom.constant=0;// 如果微博没有配图,则设置其底部与父控件之间的距离为0}

运行程序瞅一望:

澳门金冠开户 35

日运行.gif
直是两全!O(∩_∩)O~。为了证实点所说之Self-Sizing
Cells技术效率强大,大家能够拿其撤消掉,然后再次来运转品种看一下:
[图形上传遭到。。。(10)]

裁撤电动总计代码将来的运行效果.gif
撤后,程序的力量这就换挫了。与经过代码自定义不对等高cell比起来,用storyboard完成同样的效应是未是大概好多矣?不过,前边都说罢,这种技术只可以以在iOS
8及其将来的类别,假诺一旦适配iOS
7怎么处置为?作为依靠总责之好青年,下边就是起成功iOS 8往日的系适配。
五、适配iOS 8往日的网
第一来storyboard,删除知乎配图控件底部同父控件之间的这根约束。由于我们事先以到了那到底约束,所以于剔除从前先选用着其,然后右击,删除其跟pictureBottom之间的连线关系:

澳门金冠开户 36

Snip20160821_86.png
去除该约束与pictureBottom属性之间的连线关系之后,可径直以这么些打Constraints中删去了:

澳门金冠开户 37

删去今日头条配图控件底部同父控件之间的约束.jpg
进而,删除今日头条配图控件的冲天约和pictureHeight属性之间的连线关系(与方不同,本次约束不能去除):

澳门金冠开户 38

删除博客园配图控件的惊人约和pictureHeight属性之间的连线关系
少封锁与两属性之间的连线关系还不曾了,这两属性也就一贯不因而了。来到ESStatusCell.m文件,直接以这么些去:

澳门金冠开户 39

剔除多余的性能
剩余的性质为无了,那么和该属性有关的代码也就从未有过由此了,直接去解决系统报错:

澳门金冠开户 40

删除没由此底代码.png
咱们以达标一致首作品被提了,与tableView的cell低度相关的,除了rowHeight属性之外,也即便偏偏剩余-tableView:heightForRowAtIndexPath:代理方了。来到控制器,实现该办法:

#pragma mark -// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {return250;// 250是一个比较吉利的数字,在这里可以帮你解决程序报错}

即使算cell子控件的冲天,就不可以不倚重模型,在回到cell低度的法门中落实:

// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度ESStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];// 这里也要用到可重用标识符,建议将- tableView: cellForRowAtIndexPath:方法中声明可重用标识符的代码拿到外面去cell.status=self.statusArr[indexPath.row];

算算cell的万丈。假使有微博配图,我们只需要以到网易配图控件的最好特别y值,然后加上该底部同父控件之间10间距就可以;假若没天涯论坛配图,咱们才需要用到和讯文本控件,然后使用该最为老y值长10间隔就会统计出cell的低度。不过,我们后面用控件的习性表明在ESStatusCell的接近扩大中,从控制器中是不能访问的,为之,我们务必以这拿到其的峰文件被错过。也就是说,现在整个寓目图头文件化这样:

#import@classESStatus;@interfaceESStatusCell:UITableViewCell/** 用于接收来自控制器传入的模型数据 */@property(strong,nonatomic) ESStatus *status;// 模型属性// 用户头像@property(weak,nonatomic)IBOutletUIImageView*iconImageView;// 不要与tableView的imageView属性冲突// 用户昵称@property(weak,nonatomic)IBOutletUILabel*nameLabel;// 用户的VIP标识@property(weak,nonatomic)IBOutletUIImageView*vipImageView;// 用户发送的微博文字内容@property(weak,nonatomic)IBOutletUILabel*text_label;// 不要与tableView的textLabel属性冲突// 用户发送的微博配图@property(weak,nonatomic)IBOutletUIImageView*pictureImageView;@end

我们更返控制器中失去,在-
tableView:heightForRowAtIndexPath:方法被总结相关子控件的最好要命惊人,然后拿cell中度重临:

// 计算cell的高度CGFloatcellHeight =0;// 初始化cellHeight的值if(cell.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(cell.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(cell.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;

辩论及提,至此,大家的办事算大功告成了,然而,大家先行运行程序看一下:

澳门金冠开户 41

需要调试版.gif
从结果高达看,这多少个并没高达大家预料的效率,有些地点距离很老,而稍地点,网易正文文字部分显得不净。那是啊由也?想转手,大家总括cell中度的代码,实际上是遵照pictureImageView和text_label这一点儿独控件遵照约束规范完全亮出来下者前提条件的。可事实上,在大家总结cell中度的时刻,这简单只控件并不曾循相应的牢笼规范完全彰显出。由此,大家所总括的cell低度的值,并无精确。
视图中之支行控件要先行接及数码,然后才会遵照对应的牢笼原则总括起科学的frame,而子控件被之数是通过-
tableView:
cellForRowAtIndexPath:这一个方法传递过来的。另外,大家统计cell低度的代码是以-
tableView:heightForRowAtIndexPath:这一个办法中展开的。为了印证问题,我们先来经过打印,查看转当下半独法子的调用顺序:

澳门金冠开户 42

少数只点子的调用顺序
起打印结果来拘禁,- tableView:heightForRowAtIndexPath:这些法的调用要相比-
tableView:
cellForRowAtIndexPath:那多少个艺术早。也就是说,子控件还未曾收取及多少,并且,在生数据的根基及,依照提前安装的约原则,总括好子控件的frame,我们便已当-
tableView:heightForRowAtIndexPath:这些办法中把cell的可观算寿终正寝了,这样结果当然不对了!为者,我们亟须想办法,要于算cell中度的代码往日,让cell内部的分支控件按照约束原则提前总结同一整个。解决的办法是强制刷新一下:
// 强制刷新[cell layoutIfNeeded];
来拘禁一下挟制刷新后的结果:

澳门金冠开户 43

强制刷新.gif
强制刷新之后,效果是好过多了,不过文字控件部分如故发出题目。原因和地方一样,依然因为文字控件最充裕开间总计后了。我们当威胁刷新代码在此以前,先手动统计文字控件的无比可怜幅面:

// 计算文字控件的最大宽度cell.text_label.preferredMaxLayoutWidth= [UIScreenmainScreen].bounds.size.width-20;

又拘留一下程序运行的效能:

澳门金冠开户 44

低度总计了毕.gif
六、性能优化
通过前的学,大家清楚-
tableView:heightForRowAtIndexPath:这一个法调用非常累,出于程序性能方面的考虑,大家还索要针对其开相应的优化办事。
1、优化- tableView:heightForRowAtIndexPath:方法被之cell
咱俩所以要于-
tableView:heightForRowAtIndexPath:方法中开创cell,目标是以临时被该传递数据,能超前总括其里面子控件的frame。在代码优化在此以前,我们事先来打印一下这多少个方法吃所开创cell的内存地址:

澳门金冠开户 45

系统创建了无数cell
自从打印出的cell内存地址,以及右侧的直拖动条能,我们创制了老多的cell。其实并未那些必要,大家唯有待创立一个cell,然后让它赋值不同的数额就是足以了。所以,我们当用创造cell的代码变成全局变量:

ESStatusCell *cell;// 声明一个全局变量#pragma mark -
// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {if(cell ==nil) {// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    cell.status=self.statusArr[indexPath.row];// 计算文字控件的最大宽度cell.text_label.preferredMaxLayoutWidth= [UIScreenmainScreen].bounds.size.width-20;// 强制刷新[cell layoutIfNeeded];// 计算cell的高度CGFloatcellHeight =0;if(cell.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(cell.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(cell.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;}

咱俩再来打印一下cell的内存地址:

澳门金冠开户 46

实在就生平等卖cell
固然要打印了众多,可是自从内存地址来拘禁,其实这一个cell都是和一个,这样虽达成了一个特性优化的目标。
2、优化- tableView:heightForRowAtIndexPath:方法
从今前边的打印结果来拘禁,-
tableView:heightForRowAtIndexPath:方法调用分外之再三,每个cell都至少要调用一蹩脚,有些cell甚至会频调用。那么,为何而调用这么累吗?这些还得自tableView的contentSize说自。
咱都知道,苹果做业务是深重视用户体验的。在此以前边的动图我们能收看,每一遍tableView出现之后,屏幕右边会出去一个垂直的轮转条,用户可经过是滚动条大约了然后还有多少数量。而屏幕及滚条之长而跟tableView的contentSize有关。频繁的调用-
tableView:heightForRowAtIndexPath:方法,其目的就是为设置tableView的contentSize。
这样做,用户体验看起是科学,然则,当tableView有诸多分组,且每组又起诸多风靡,那么那法子的调用频率将是可怜可观之。有时候一个App打开将来,屏幕会先出现白屏,然后又加载tableView的数码,或多或少是坐这一个由。苹果为发觉及了之题材,所将来来便出了电动估量技术。
机动臆想技术既可保证App加载时让tableView设置合适的contentSize,又可以缓解程序性能问题。接下来我们以研商一下自行揣摸技术。
咱于本文中提到过,在设置tableView的estimatedRowHeight属性的值时,只要大于0就好,其实那些价值的装为是起自然技巧的。通常状态下,我们会合给此特性赋值44,因为系统的cell默认中度就是44。不过,作为以项目而言,我们了可用她的值设大一点。
我们事先经打印领会一下,在无设置estimatedRowHeight属性值时的情况:

澳门金冠开户 47

勿设置estimatedRowHeight属性的价值的前.png
从今结果及看,打印是深之多。我们还来拘禁一下,将estimatedRowHeight属性的值设置也44之后的图景:

澳门金冠开户 48

只有9条数据
于打印结果来拘禁,打印显然滑坡了,只爆发9长长的。大家重来拘禁一下,将estimatedRowHeight属性的值设置也100从此的情:

澳门金冠开户 49

打印结果越减弱及7漫漫数据.png
打印结果再一次少了,只出7久数据。我们重来拘禁一下,将estimatedRowHeight属性的价设置也200后头的动静:

澳门金冠开户 50

打印结果但出5漫长.png
我们看,打印结果单残留5条了。我们又来拘禁一下,将estimatedRowHeight属性的值设置也1000随后的情事:

澳门金冠开户 51

打印结果依然5长条.png
自家于是这样执着于打印,并无是因我是打印狂魔,更无是为凑篇幅,而是为声明问题。没有发觉,我老是上打印截图的当儿,都管控制器屏幕一起截在内?其实,这些estimatedRowHeight属性的价值是和大家的屏幕中度,以及tableView下面cell的骨子里低度有关的!
自己所以的模拟器是索尼爱立信6s,它的屏幕低度也667,而屏幕上本会望底cell数量正是5个。我们首先不良设置estimatedRowHeight属性的价是44,667
/ 44 =
15.1,理论及说,应该会打印16长达信息,不过因为我们的tableView总共只生9长长的cell,因而只打印9长条音信。第二蹩脚我们设置estimatedRowHeight属性的价值吗100随后,屏幕打印出7漫长信息,是盖667
/ 100 =
6.67,所以打印7漫漫消息。不过,只要我们estimatedRowHeight属性的价超出667 /
5 =
133.4事后,控制台打印出的信息永远都只是发5长达,这是盖我们我们屏幕上本亮的刚巧是5长条。
透过者的分析,大家可得出这样一个定论:合理的安estimatedRowHeight属性的价,可以有效压缩-
tableView:heightForRowAtIndexPath:方法的调用次数,从而达到优化程序性能的目标。可是,这多少个属于性值的高低和屏幕中度,以及cell的莫过于中度相关,既非是更为小更好,也无是尤为老更是好。

除去可经tableView的estimatedRowHeight性能实现全自动揣测技术外,还可兑现代理的
tableView: estimatedHeightForRowAtIndexPath:
主意齐同等的目标。
3、优化总计cell中度的设计方案
俺们的代码还有其余一个题材。记忆一下咱事先所法到之知,就是一个控件内部私有的性质,最好是声称在类似增加中,不要透露于外面。不过,大家当地点总括cell低度时,恰恰违反了那些法。为了可以在控制器中以到视图内部的系控件,大家用ESStatusCell的民用属性移到了ESStatusCell.h文件被,这样做是休安全之。为是,我们亟须想一个计,在既非违反规划基准的气象下,又能叫外界抱cell的真低度。
缓解案是,把统计cell真实低度的那有些代码封装于ESStatusCell这么些类似里,然后再以计结果回到,以供外界调用。具体操作是,在ESStatusCell.h文件被宣示一个cellHeight属性,然后在ESStatusCell.m文件中重新写cellHeight的getter方法,最后,控制器可以因而看cell的cellHeight属性获取相应的结果。
从而,ESStatusCell.h文件最后的代码应该是:

#import@classESStatus;@interfaceESStatusCell:UITableViewCell/** 用于接收来自控制器传入的模型数据 */@property(strong,nonatomic) ESStatus *status;// 模型属性// 提供计算cell高度的借口@property(assign,nonatomic)CGFloatcellHeight;@end

重写cellHeight的getter方法:

// 返回cell的高度。因为- tableView:heightForRowAtIndexPath:方法的关系,这个调用也很频繁- (CGFloat)cellHeight {// 计算文字控件的最大宽度// self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;// 强制刷新[selflayoutIfNeeded];// 计算cell的高度CGFloatcellHeight =0;if(self.status.picture) {// 如果微博有配图cellHeight =CGRectGetMaxY(self.pictureImageView.frame) +10;// 微博配图控件的最大y值加上10间距就是cell的高度}else{// 如果没有微博配图cellHeight =CGRectGetMaxY(self.text_label.frame) +10;// 微博文本控件的最大y值加上10间距就是cell的高度}returncellHeight;}

唯独假使顾,因为- tableView:heightForRowAtIndexPath:方法的涉及,-
cellHeight那一个措施的调用也颇频繁,而计量网易文本控件的相当要命幅面仅待算同一不行,所以可以设想用其在-
awakeFromNib方法被推行:

- (void)awakeFromNib {// 计算文字控件的最大宽度self.text_label.preferredMaxLayoutWidth= [UIScreenmainScreen].bounds.size.width-20;}
  • tableView:heightForRowAtIndexPath:方法以外围通过拜访cell的cellHeight属性,获取cell的真正中度:

ESStatusCell *cell;#pragma mark -// 返回cell的高度- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {if(cell ==nil) {// 拿到indexPath.row这行cell对应的模型,借助模型获取cell内部子控件的高度cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    cell.status=self.statusArr[indexPath.row];returncell.cellHeight;// 返回cell的高度}

原稿链接:http://www.jianshu.com/p/35f5b68bbe4a