文档章节

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

ios122
 ios122
发布于 2015/09/23 17:22
字数 1989
阅读 97
收藏 4

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

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

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

网易新闻

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

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

新浪微博

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

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

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

1.文字高度计算时 0.1 高度误差问题.

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

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

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

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

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

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

1.使用AutoLayout 布局你的cell

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

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

博客讨论

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

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

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

示例下载地址: 点击下载

非常感谢 @未来帅哥 的讨论,给了我很大启发和帮助,我也如约做了一个关于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,耐心研究几个小时,绝对让你受益匪浅!

© 著作权归作者所有

共有 人打赏支持
ios122
粉丝 72
博文 76
码字总数 132179
作品 3
东城
程序员
私信 提问
有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

Apple 算是最重视应用开发体验的公司了。从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利。但是,对于绝对多数iOS攻城狮来说,我们依然还是...

hejunbinlan
2015/10/15
72
0
Auto Layout + Manual Layout 混用

约束代码混用的问题 无数人趟过此坑,大部分人在坑中一蹶不振,小部分人爬起来也是跌跌撞撞。 有很多人都说auto layout和manual layout的坐标设置是不能混用的,会导致出现布局问题。首先声明...

人独立
2015/12/04
252
0
IOS 6 自动布局 入门-1

来自Ray:恭喜各位!你们已经通过宣传ios feast提前解锁了第一个有关IOS6的教程。 目前这份教程只是我们的新书iOS 6 By Tutorials里面某个章节的精简版。这份教程由同样著作过iOS Apprentic...

青云_K
2013/01/15
0
0
IOS 6 自动布局 入门 2

来自Ray:恭喜各位!你们已经通过宣传ios feast提前解锁了第一个有关IOS6的教程。 目前这份教程只是我们的新书iOS 6 By Tutorials里面某个章节的精简版。这份教程由同样著作过iOS Apprentic...

青云_K
2013/01/05
0
0
ExtJS 4.x中的布局(layouts in ExtJS 4.x)(一)

一、布局的来源(Why we need layout) 页面上显示的各个元素往往是嵌套的,这些元素在页面上的摆放需要某些元素能够盛放其他一些元素,因此就有了Container(“容器”,一种特殊组件)和Com...

李词超
2013/11/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

设计模式之单例模式

单例模式核心:保证一个类只有一个对象 单例模式分为五种:懒汉式、饿汉式、双重检测锁式、静态内部类式、枚举式 五种模式的特点:懒汉式---线程安全,调用效率高,不能延时加载 饿汉式---线...

森林之下
13分钟前
0
0
markdown语法

这篇博客是本人在使用markdown语法过程中,用于记录一些自己总是会忘记的语法,并且会持续更新; 如何增加批注/备注:>; 这是一条备注/引言 如何手动换行,行末两次空格;

BlackCanary
14分钟前
1
0
redis 设置外网可访问

前提是你已经把redis的端口放到了防火墙计划中,  /sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT /etc/rc.d/init.d/iptables save 更改redis.conf 文件 bind 127.0.0.1prot...

时刻在奔跑
16分钟前
0
0
css3隐藏滚动条

chrome 和Safari .element::-webkit-scrollbar { width: 0 } IE 10+ .element { -ms-overflow-style: none; } Firefox .element { overflow: -moz-scrollbars-none; } firefox这个没试过~啦啦......

呵呵闯
32分钟前
0
0
Poco官方PPT_020-ErrorHandlingAndDebugging双语对照翻译

因工作需要用到这一块的功能,所以直接翻译了一下 此PPT来源于官方文件,地址https://pocoproject.org/documentation.html

CHONGCHEN
36分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部