Apple 算是最重视应用开发体验的公司了.从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利.可是,对于绝对多数iOS攻城狮来讲,咱们依然仍是很惧怕写UITabelVIew的自适应布局.固然,惧怕不是由于咱们不会写,或者自己有什么特殊的技术点,而是由于太麻烦.固然,文章的后半部分,会给出相应的解决方案,毕竟本文不是为了吐槽而吐槽.html
以网易新闻的客户端为例,可能的数据包括文字新闻,图片新闻,图集,推广,视频等.每一种数据,又根据来源或点击量等细分出许多不一样的状态.基本上每种数据类型,都至少须要一种单独的Cell去呈现,每个Cell的布局,都要单独去写.因此说,数据的类型将直接决定页面自己的复杂度.ios
上图取自新浪微博.稍微有点经验的iOS攻城狮,都猜到我要吐槽什么了吧!没错,就是同种数据类型,可是内部字段的长度可能不一样,并且还要都要给他们显示出来!其实我也很但愿自家的应用都像网易那样,固定长度显示新闻,显示不完,就直接截断--惋惜那样的应用都是别人公司的应用.可能你会说: 顶部给个非微博正文区域给个固定高度;文字区域动态计算出高度;图片部分,图片高度固定,根据数量动态计算高度;转发部分同理;而后根据数据在tabelView的代理方法 tableView:heightForRowAtIndexPath:
中动态返回高度便可.是的,思路就是这么个思路,可是你肯定产品经理一直不会改需求?你肯定不须要适配 6plus时,字号要大点?你肯定本身的应用不但愿大屏上同样能显示更多的图片?你肯定老板不是盘算着 iPad版也交给你维护?因此说,对于这种数据长度不肯定,可是又要求彻底显示的设计,最复杂的不在于实现,而在于后期的迭代.可变字段越多,迭代越复杂.若是连显示方式都改了,那就基本等于重作了几遍.git
在 tableView:heightForRowAtIndexPath:
中计算高度时,是有坑的,对于刚接触iOS的攻城狮来讲,几乎是难以理解的诡异问题.这里简单说两个,其余的你们可跟帖补充:github
cell中常常须要使用 textRectForBounds: limitedToNumberOfLines:
来计算某一个文字的显示高度.这里,其实有一个很大的坑的,若是你没遇到只能说明你很幸运.因为浮点数四舍五入机制的存在,因此偶现UILabel最后一行没法显示的状况.缘由也很诡异: 在你计算时,部分值会存在稍许的不超过0.01的偏差,大多数状况下,这个偏差值,能够安全忽略,可是确实存在那0.01偏差恰好是绝对换行与不换行的分界值,由于0.01的偏差,可能计算出来的高度就不足以显示最后几个文字.为了安全起见,若是须要计算文本高度,我都是加上一个额外的0.1来保证最后一行确定能够显示.安全
这个可能也是一些有经验的开发者也会混淆的问题: 不要在本身的代码中调用 tableView:cellForRowAtIndexPath:
方法来获取某一个位置的 cell,来进行关于这个cell的某些计算,由于你手动调用这个方法产生的cell不会参与cell的复用! 各类原因,不过多解释,总之结论就是,只要系统本身调用 tableView:cellForRowAtIndexPath:
方法产生的 cell才会参与cell的复用.
关于这个话题,比较易犯的错误是,居然有开发者在less
tableView:heightForRowAtIndexPath:
中调用 tableView:cellForRowAtIndexPath:
来获取cell,而后计算cell高度.而后你会发现,凡是稍微涉及到图片显示的界面,你的显示是对的,可是滚动很是卡顿,由于你在本身浑然不觉的状况下建立了N个Cell,并且这些Cell绝对不会参与复用.布局
是的,我如今一点也不担忧去处理各类UITabelView布局.不是由于我有一股所谓的不畏艰难的伟大工做精神,而是由于我切实找到了解决办法.具体该怎么作呢?优化
坦白说,咱都是刚入行的人,使用AutoLayout布局,写一个自适应的Cell,你们估计也都会.能够用xib,也能够用纯代码写.若是准备用纯代码写,建议你先好好研究下 Masonry — 使用纯代码进行iOS应用的autolayout自适应布局spa
坦白说,我原来也是: 虽然cell用着AutoLayout,可是计算cell高度时,也是看着设计图返回一个适合的值--想一想都虐心.前天,一个热心的开发者在我博客留言说: 他用 Masonry 进行Cell的高度自适应时遇到了问题.我第一反应是: Masonry 能用来计算cell高度?! 而后,他提到了一个第三方UITableView-FDTemplateLayoutCell,好像是国内的大神写的,具体介绍能够看这里: 优化UITableViewCell高度计算的那些事.这篇文章的博主关于 UITableView-FDTemplateLayoutCell 分析很详尽,用一句总结就是: 一行代码解决cell高度动态计算问题.设计
示例下载地址: 点击下载
很是感谢 @将来帅哥 的讨论,给了我很大启发和帮助,我也如约作了一个关于Masonry 和 UITableView-FDTemplateLayoutCell结合使用的小例子,以解决他的问题:关于如何让左侧图片底部老是不被遮盖.
核心代码片断:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat height = [tableView fd_heightForCellWithIdentifier: NSStringFromClass([YFAutoLayoutCell class]) cacheByIndexPath:indexPath configuration:^(YFAutoLayoutCell * cell) { YFAutoLayoutCellModel * model = [self.data objectAtIndex: indexPath.row]; cell.model = model; }]; return height; }
/** * 初始化视图. */ - (void) setupView { self.imgView = [[UIImageView alloc] init]; self.introLabel = [[UILabel alloc] init]; [self.contentView addSubview: self.imgView]; [self.contentView addSubview: self.introLabel]; self.introLabel.numberOfLines = 0; [self.imgView makeConstraints:^(MASConstraintMaker *make) { make.top.left.equalTo(8); make.size.equalTo(CGSizeMake(60, 60)); make.bottom.lessThanOrEqualTo(-8); // 这里是关键 }]; [self.introLabel makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.imgView.right).offset(8); make.top.equalTo(self.imgView); make.right.equalTo(-8); make.bottom.equalTo(-8); }]; }
有了Auto Layout,为何你仍是惧怕写UITabelView的自适应布局?由于你还在用传统的方式去计算cell的高度! Auto Layout + UITableView-FDTemplateLayoutCell + Masonry,耐心研究几个小时,绝对让你受益不浅!