本文是投稿文章,作者:iOS122


Apple 算是最重视应用开发体验的公司了。从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利。但是,对于绝对多数iOS攻城狮来说,我们依然还是很害怕写UITabelVIew的自适应布局。当然,害怕不是因为我们不会写,或者本身有什么特殊的技术点,而是因为太麻烦。当然,文章的后半部分,会给出相应的解决方案,毕竟本文不是为了吐槽而吐槽。

UITabelView的自适应布局有多麻烦?

数据类型的不确定性:种类越多,页面越复杂。

网易新闻

以网易新闻的客户端为例,可能的数据包括文字新闻,图片新闻,图集,推广,视频等。每一种数据,又根据来源或点击量等细分出许多不同的状态。基本上每种数据类型,都至少需要一种单独的Cell去呈现,每一个Cell的布局,都要单独去写。所以说,数据的类型将直接决定页面本身的复杂度。

数据长度的不确定性: 不确定字段越多,迭代成本越高。

新浪微博

上图取自新浪微博。稍微有点经验的iOS攻城狮,都猜到我要吐槽什么了吧!没错,就是同种数据类型,但是内部字段的长度可能不同,而且还要都要给他们显示出来!其实我也很希望自家的应用都像网易那样,固定长度显示新闻,显示不完,就直接截断--可惜那样的应用都是别人公司的应用。可能你会说: 顶部给个非微博正文区域给个固定高度;文字区域动态计算出高度;图片部分,图片高度固定,根据数量动态计算高度;转发部分同理;然后根据数据在tabelView的代理方法 tableView:heightForRowAtIndexPath: 中动态返回高度即可。是的,思路就是这么个思路,但是你确定产品经理一直不会改需求?你确定不需要适配 6plus时,字号要大点?你确定自己的应用不希望大屏上一样能显示更多的图片?你确定老板不是盘算着 iPad版也交给你维护?所以说,对于这种数据长度不确定,但是又要求完全显示的设计,最复杂的不在于实现,而在于后期的迭代。可变字段越多,迭代越复杂。如果连显示方式都改了,那就基本等于重做了几遍。

cell高度计算有坑: 难以理解的诡异问题

在 tableView:heightForRowAtIndexPath: 中计算高度时,是有坑的,对于刚接触iOS的攻城狮来说,几乎是难以理解的诡异问题。这里简单说两个,其他的大家可跟帖补充:

  • 文字高度计算时 0.1 高度误差问题。

cell中经常需要使用 textRectForBounds: limitedToNumberOfLines: 来计算某一个文字的显示高度。这里,其实有一个很大的坑的,如果你没遇到只能说明你很幸运。由于浮点数四舍五入机制的存在,所以偶现UILabel最后一行无法显示的情况。原因也很诡异: 在你计算时,部分值会存在稍许的不超过0。01的误差,大多数情况下,这个误差值,可以安全忽略,但是确实存在那0。01误差刚好是绝对换行与不换行的分界值,因为0。01的误差,可能计算出来的高度就不足以显示最后几个文字。为了安全起见,如果需要计算文本高度,我都是加上一个额外的0。1来保证最后一行肯定可以显示。

  • 手动调用 tableView:cellForRowAtIndexPath: 获取cell,引起的卡顿问题。

这个可能也是一些有经验的开发者也会混淆的问题: 不要在自己的代码中调用 tableView:cellForRowAtIndexPath: 方法来获取某一个位置的 cell,来进行关于这个cell的某些计算,因为你手动调用这个方法产生的cell不会参与cell的复用! 各种缘由,不过多解释,总之结论就是,只要系统自己调用 tableView:cellForRowAtIndexPath: 方法产生的 cell才会参与cell的复用。

关于这个话题,比较易犯的错误是,竟然有开发者在tableView:heightForRowAtIndexPath: 中调用 tableView:cellForRowAtIndexPath: 来获取cell,然后计算cell高度。然后你会发现,凡是稍微涉及到图片显示的界面,你的显示是对的,但是滚动非常卡顿,因为你在自己浑然不觉的情况下创建了N个Cell,而且这些Cell绝对不会参与复用。

为什么我现在不再害怕写UITabelView的自适应布局?

是的,我现在一点也不担心去处理各种UITabelView布局。不是因为我有一股所谓的不畏艰难的伟大工作精神,而是因为我切实找到了解决办法。具体该怎么做呢?

  • 使用AutoLayout 布局你的cell

坦白说,咱都是刚入行的人,使用AutoLayout布局,写一个自适应的Cell,大家估计也都会。可以用xib,也可以用纯代码写。如果准备用纯代码写,建议你先好好研究下 Masonry - 使用纯代码进行iOS应用的autolayout自适应布局

  • 使用 UITableView-FDTemplateLayoutCell 根据单元格内容的约束自适应单元格高度

博客讨论

坦白说,我原来也是: 虽然cell用着AutoLayout,但是计算cell高度时,也是看着设计图返回一个适合的值--想想都虐心。前天,一个热心的开发者在我博客留言说: 他用 Masonry 进行Cell的高度自适应时遇到了问题。我第一反应是: Masonry 能用来计算cell高度?! 然后,他提到了一个第三方UITableView-FDTemplateLayoutCell,好像是国内的大神写的,具体介绍可以看这里: 优化UITableViewCell高度计算的那些事。这篇文章的博主关于 UITableView-FDTemplateLayoutCell 分析很详尽,用一句总结就是: 一行代码解决cell高度动态计算问题。

  • 一个关于Masonry 和 UITableView-FDTemplateLayoutCell结合使用的小例子

一个关于Masonry 和 UITableView-FDTemplateLayoutCell结合使用的小例子

示例下载地址: 点击下载

非常感谢 @未来帅哥 的讨论,给了我很大启发和帮助,我也如约做了一个关于Masonry 和 UITableView-FDTemplateLayoutCell结合使用的小例子,以解决他的问题:关于如何让左侧图片底部总是不被遮盖。

核心代码片段:

1
2
3
4
5
6
7
8
9
10
11
- (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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 *  初始化视图.
 */
- (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,耐心研究几个小时,绝对让你受益匪浅!

转载于:https://www.cnblogs.com/easyToCode/p/5196303.html

有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?相关推荐

  1. iOS屏幕适配方案-Auto Layout

    市场上的android手机五花八门.各种尺寸的屏幕让android程序员们比較头疼. 也有一些大神写了一些博客提出了自己的观点.iOS貌似也迎来了大屏6+,因此屏幕适配的问题也是有滴,因此苹果也有自己 ...

  2. IOS开发高手课第三篇 App Auto Layout 是怎么进行自动布局的,性能如何?

    03 | Auto Layout 是怎么进行自动布局的,性能如何? Auto Layout ,是苹果公司提供的一个基于约束布局,动态计算视图大小和位置的库,并且已经集成到了 Xcode 开发环境里. ...

  3. Unity/Auto Layout -- 理解Layout Elements(布局元素)

    前言 在UGUI1中,Canvas下的每个GameObject都会自动添加 Rect Transform 组件来控制自身的位置和大小.通常情况下,基于Rect Transform的布局系统已经足够灵活 ...

  4. 学会爱上iOS自动布局(Auto Layout)

    本文翻译自Yari Dareglia的LEARN TO LOVE AUTO LAYOUT文章 先生们,女士们,让我们以正确的心态开始本教程吧:自动布局就是简单! 我花了一段时间来掌握自动布局是如何工作 ...

  5. Advanced Auto Layout:Programmatically Creating Constraints

    Programmatically Creating Constraints以编程方式创建约束 Whenever possible, use Interface Builder to set your ...

  6. 【Auto Layout】Xcode6及以上版本,创建Auto Layout 约束时产生的一些变化【iOS开发教程】...

    [#Auto Layout#]Xcode6创建Auto Layout 约束时产生的一些变化     通过两个小Demo来展示下变化: Demo1需求: 为控制器的根视图(图中的"控制器Vie ...

  7. 转载:使用Auto Layout中的VFL(Visual format language)--代码实现自动布局

    本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:API介绍 NSLayoutConstraint API 1 2 3 ...

  8. iOS6 自动布局 入门–Auto Layout(转)

    iOS6 自动布局 入门–Auto Layout(转) 标签: 杂谈   目前为止,即使你的界面设计是在合理的复杂度内,你也必须要为之写许多代码来适应变化的布局.现在我相信你会很高兴听到这种情况将不会 ...

  9. Unity2017.1官方UGUI文档翻译——Auto Layout

    Auto Layout 自动布局 The Rect Transform layout system is flexible enough to handle a lot of different ty ...

最新文章

  1. pandas 设置多重索引_Pandas多重索引使用详解
  2. Excel对重复数据分组,求出不同的数据(office 2013)
  3. Hdu 1312 Red and Black
  4. spring里头各种获取ApplicationContext的方法
  5. java date 操作类_JAVA时间操作类常用方法汇总
  6. 利用WinRAR命令行压缩文件或文件夹
  7. 【转】NI语法 JNI参考 JNI函数大全
  8. 两年前搭建的网狐系统
  9. Python是什么?Python能干什么?一篇文章让你对Python了如指掌!!
  10. android8.1 audio hal关键结构分析(二十五)
  11. 游戏算法整理(贴图完整版)
  12. .NetCore对接各大财务软件凭证API——金蝶系列(2)
  13. 孤独求败:美国海军邀黑客“黑掉军舰”
  14. C++程序避免触发 Win7下的程序兼容助手
  15. 基于PHP+MySQL的美容会所企业资产管理系统
  16. Shell脚本实现自动检测/配置/开启/关闭redis后台服务
  17. P1085 [NOIP2004 普及组第一题] 不高兴的津津 ← 模拟题
  18. 在一幅图中为箱线图设置不同颜色
  19. weex项目实战篇(二)
  20. 头歌实训项目【学生信息转换】

热门文章

  1. 深度优先搜索算法的通用解法
  2. dac生成信号频率取决于_信号发生器和DA转换 FPGA案例教程
  3. Direct3d 显示视频的一个问题
  4. c++11测试时间封装
  5. coreboot学习10:coreboot第一阶段学习小结
  6. Oracle和Mysql的不同
  7. simulink和psim仿真结果不同_(格麟倍)航空航天零件硬铬电镀工艺专业仿真评估工具...
  8. 【Flink】Flink 如何在本地IDEA恢复检查点 不通过IDEA 不通过 flink run 方法
  9. 95-860-050-源码-定时器-InternalTimeServiceManager
  10. 【Elasticsearch】搜索基准测试:RediSearch 与 Elasticsearch