iOS 8 自适应 Cell

2023-05-16

在使用 table view 的时侯经常会遇到这样的需求:table view 的 cell 中的内容是动态的,导致在开发的时候不知道一个 cell 的高度具体是多少,所以需要提供一个计算 cell 高度的算法,在每次加载到这个 cell 的时候计算出 cell 真正的高度。

在 iOS 8 之前

没有使用 Autolayout 的情况下,需要实现 table view delegate 的 tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 方法,在这个方法中计算并返回 cell 的高度。比如,我有一个可以显示任意行数的纯文本 cell,计算 cell 的代码可以是这样:

1
2
3
4
5
6
7
8
9
10
11
12
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
     let content = self.datas[indexPath.row] as String
     let padding: CGFloat = 20
     let width = tableView.frame.size.width - padding * 2;
     let size = CGSizeMake(width, CGFloat.max)
     let attributes = [NSFontAttributeName: UIFont(name:  "Helvetica" , size: 14)!]
     let frame = content.boundingRectWithSize(size,
         options: NSStringDrawingOptions.UsesLineFragmentOrigin,
         attributes: attributes,
         context: nil)
     return  frame.size.height+1;
}

上面的代码是一个最简单的例子,这个例子看起来好像没有什么问题。但是通过查看这个 delegate 方法的文档后,可以知道,在每次 reload tableview 的时候,程序会先计算出每一个 cell 的高度,等所有高度计算完毕,确定了 tableview 的总的高度后,才开始渲染视图并显示在屏幕上。这意味着在显示 table view 之前需要执行一堆的计算,并且这是在主线程中进行的,如果计算量太大程序就很有可能出现卡顿感。比如: table view 的数据有上千条,或者计算高度的代码中还要先获取图片再根据图片计算高度,这些操作都是非常慢的。

如果在 cell 中使用了 autolayout,在计算 cell 高度时会更麻烦。有兴趣的可以看这里有篇关于如何在 autolayout 下动态计算高度的文章。

为什么不能等滚动到某个 cell 的时候,再调用计算这个 cell 高度的 delegate 呢?原因是 tableview 需要获得它的内容的总高度,用这个高度去确定滚动条的大小等。直到 iOS 7 UITableViewDelegate中添加了新的 API:

1
tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

这个方法用于返回一个 cell 的预估高度,如果在程序中实现了这个方法,tableview 首次加载的时候就不会调用heightForRowAtIndexPath 方法,而是用 estimatedHeightForRowAtIndexPath 返回的预估高度计算 tableview 的总高度,然后 tableview 就可以显示出来了,等到 cell 可见的时候,再去调用heightForRowAtIndexPath 获取 cell 的正确高度。

通过使用estimatedHeightForRowAtIndexPath 这个 Delegate 方法,解决了首次加载 table view 出现的性能问题。但还有一个麻烦的问题,就是在 cell 没有被加载的时候计算 cell 的高度,上面给出的代码中,仅仅是计算一个 NSString 的高度,就需要不少代码了。这种计算实际上是必须的,然而在 iOS 8 开始,你可能可以不用再写这些烦人的计算代码了!

iOS 8 的魔法

在 iOS 8 中,self size cell 提供了这样一种机制:cell 如果有一个确定的宽度/高度,autolayout 会自动根据 cell 中的内容计算出对应的高度/宽度。

TableView 中的 cell 自适应

要让 table view 的 cell 自适应内容,有几个要点:

1.设置的 AutoLayout 约束必须让 cell 的 contentView 知道如何自动延展。关键点是 contentView 的 4 个边都要设置连接到内容的约束,并且内容是会动态改变尺寸的。

2.UITableView 的 rowHeight 的值要设置为 UITableViewAutomaticDimension

3.和 iOS 7 一样,可以实现 estimatedHeightForRowAtIndexPath 方法提升 table view 的第一次加载速度。

4.任何时候 cell 的 intrinsicContentSize 改变了(比如 table view 的宽度变了),都必须重新加载 table view 以更新 cell。

例子

在 Xcode 中新建一个项目,在 storyboard 中创建一个 UITableViewController 的 IB,创建一个如下样子的 cell:

2014-11-13-self-size-cell-1.jpg

这个 cell 中有 3 个元素,其中 imageView 的 autoLayout 约束为:

imageView 左边离 contentView 左边 0

imageView 上边离 contentView 上边 0

imageView 的 width 和 height 为 80

imageView 下边离 contentView 下边大于等于 0(为了防止内容太少,导致 cell 高度小于图片高度)

titleLabel 的 autoLayout 约束为:

titleLabel 左边离 imageView 右边 8

titleLabel 上边和 imageView 上边在同一只线上

titleLabel 右边离 contentView 右边 0

titleLabel 下边离 description 上边 8

titleLabel 的高度小于等于 22,优先级为 250

descriptionLabel 的约束为:

descriptionLabel 左边和 titleLabel 左边在同一直线上

descriptionLabel 上边里 titleLabel 8

descriptionLabel 下边里 contentView 下边 0

descriptionLabel 右边离 contentView 右边 0

然后在这个 IB 对应的 UITableViewController 中加载一些数据进去,显示效果如图:

2014-11-13-self-size-cell-2.jpg

实现这个效果,我除了设置了 autoLayout,还设置了 tableView 的 rowHeight = UITableViewAutomaticDimension,然后就是这样了。一点计算 cell 高度的代码都没有!!我连 heightForRowAtIndexPath都不用实现,真的是….爽出味啊!所以如果已经在开发 iOS 8 Only 的应用了一定要用autolayout,把烦人的计算交给 autolayout 去吧。

CollectionView 中的 cell 自适应

在 collection view 中也能让 cell 自适应内容大小,如果 UICollectionView 的 layout 是一个 UICollectionViewFlowLayout,只需要将 layout.itemSize = ... 改成 layout.estimatedItemSize = ...。 只要设置了 layout 的 estimatedItemSize,collection view 就会根据 cell 里面的 autolayout 约束去确定cell 的大小。

原理:

1.collection view 根据 layout 的 estimatedItemSize 算出估计的 contentSize,有了 contentSize collection view 就开始显示

2.collection view 在显示的过程中,即将被显示的 cell 根据 autolayout 的约束算出自适应内容的 size

3.layout 从 collection view 里获取更新过的 size attribute

4.layout 返回最终的 size attribute 给 collection view

5.collection 使用这个最终的 size attribute 展示 cell

总结

这次 iOS 8 的发布对 UI 开发来说是越来方便了,很多以前需要写大量计算的代码现在都可以通过拖拖 IB 上的 UI 控件就可以实现了,当然首先你要会 autolayout。 如果很幸运的在开发 iOS 8 only 的应用,真的可以删除heightForRowAtIndexPath中那些繁重的计算代码了!让 autolayout 帮我们完成所有的工作吧。

 
 

转载于:https://www.cnblogs.com/itlover2013/p/4173872.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 8 自适应 Cell 的相关文章

随机推荐

  • Ubuntu下编译安装MySQL5.7

    tar zxvf mysql 5 7 14 tar gz cd mysql 5 7 14 第一步 xff1a cmake DCMAKE INSTALL PREFIX 61 usr local mysql DMYSQL DATADIR 61
  • UNICODE使用的一些知识和技巧

    UNICODE宏和 UNICODE宏的关系 在windows编程中 经常要编译Unicode版本的程序 方法是工程文件的配置中加上UNICODE或者 UNICODE编译条件 那么到底是用哪一个呢 Jeffrey Richter在 Windo
  • cmake 常用命令

    1 使用日期 获取时间 string TIMESTAMP DATE TIME 34 y m d H M 34 获取日期 string TIMESTAMP DATE VERSION 34 m d 34 转载于 https www cnblog
  • QQ2008 msg.db,user.db读取

    Saturday November 27 2010 msg db读取 下载 user db读取 下载 转载于 https www cnblogs com ycdx2001 archive 2010 11 27 1889498 html
  • MongoDB——Mac环境搭建

    1 下载 官网地址 xff1a https www mongodb com 2 解压并配置 解压到 usr local 配置Path xff0c vim打开 bash profile添加export PATH 61 PATH usr loc
  • Django模型

    模型是你的数据的唯一的 权威的信息源 它包含你所储存数据的必要字段和行为 通常 xff0c 每个模型对应数据库中唯一的一张表 1 基础 每个模型都是django db models Model 的一个Python 子类 模型的每个属性都表示
  • 速度之王 — LZ4压缩算法(二)

    LZ4 Extremely Fast Compression algorithm 项目 xff1a http code google com p lz4 作者 xff1a Yann Collet 本文作者 xff1a zhangskd 64
  • dpkg

    dpkg error dpkg status database is locked by another process 无法获得锁 var lib apt lists lock open ubuntu升级错误或强制中断后容易爆出上面两个错
  • html5中加一个链接,HTML5教程—链接的添加方式_HTML5教程_链接添加_HTML5运用_课课家...

    HTML5的强大功能有很多 xff0c 在图像的修改中 xff0c 我们可见其强大 xff0c 然而其中有一个功能仍能可以运用于广告中的 xff0c 因为在广告主的需求中 xff0c 有很多情况下需要在动画中添加一些外部链接 而这份文档就在
  • Django--初始化

    1 Django介绍 它是一个WEB框架 Django 大而全tornado flask 小而精 2 Django安装 https www djangoproject com download 3 创建django程序 手动创建 file
  • ubuntu更换源后报错:W: GPG error: (转载)

    From xff1a http www njava com njava 626 html 更换163源后 xff0c 更新源时出现错误 apt get update W GPG error http extras ubuntu com pr
  • 魔咒词典

    题目描述 哈利波特在魔法学校的必修课之一就是学习魔咒 据说魔法世界有100000种不同的魔咒 xff0c 哈利很难全部记住 xff0c 但是为了对抗强敌 xff0c 他必须在危急时刻能够调用任何一个需要的魔咒 xff0c 所以他需要你的帮助
  • 禁用计算机上的所有鼠标加速,鼠标加速,小编告诉你鼠标加速怎么关

    我们在使用电脑的时候经常都会需要使用到鼠标 xff0c 所以对于鼠标的相关知识我们应该要了解的多一些 所以今天小编就来给你们讲讲鼠标加速要怎么关 xff0c 感兴趣的小伙伴们就接着看下去吧 小伙伴们 xff0c 小编今天来给你们说说关于电脑
  • 位运算之左移右移运算之详解

    先看如下一段左移右移的代码及其结果 xff1a 代码 include 34 stdio h 34 char leftshift char i int n if n lt 0 return 1 return i lt lt n
  • linux安装debian桌面,在Debian 10 Buster上安装Cinnamon桌面环境的方法

    在本文中 xff0c 我们将介绍在Debian 10 Buster 操作系统上安装Cinnamon桌面环境的方法 安装Debian 10 Buster之后 xff0c 可能需要将桌面环境更改为你喜欢的桌面环境 xff0c 默认安装搭载Gno
  • MongoDB——更新文档详解

    更新文档 span class token comment 语法 span db span class token punctuation span collection span class token punctuation span
  • CCF-CSP题解 201609-3 炉石传说

    模拟 注意随从的编号在 summon 和 attack 随从死亡时都可能改变 code include lt bits stdc 43 43 h gt using namespace std struct tNode int attack
  • USACO Network of Schools(学校网络) ---强连通分量

    描述 一些学校的校园网连接在一个计算机网络上 学校之间存在软件支援协议 每个学校都有它应支援的学校名单 xff08 学校a支援学校b xff0c 并不表示学校b一定支援学校a xff09 当某校获得一个新软件时 xff0c 无论是直接得到的
  • iOS开发-使用Storyboard进行界面跳转及传值

    前言 xff1a 苹果官方是推荐我们将所有的UI都使用Storyboard去搭建 xff0c Storyboard也是一个很成熟的工具了 使用Storyboard去搭建所有界面 xff0c 我们可以很迅捷地搭建出复杂的界面 xff0c 也就
  • iOS 8 自适应 Cell

    在使用 table view 的时侯经常会遇到这样的需求 xff1a table view 的 cell 中的内容是动态的 xff0c 导致在开发的时候不知道一个 cell 的高度具体是多少 xff0c 所以需要提供一个计算 cell 高度