iOS cell高度自适应 - 教你写出优雅的table view

2023-05-16

作为一个iOS开发者,自然少不了了table view打交道,table view中最令人头疼的是各种cell的高度计算了,虽然技术上并不难,但是对于自定义cell来说一旦控件比较多,计算起来就会很麻烦,会出现很多和height相关的代码,万一稍有偏差,就要小心老板和测试大虾们鄙视的小眼神了。
今晚呢,现在已经是凌晨了~
下面就为大家介绍一种方法,让你的cell彻底丢弃HEIGHT这玩意儿~

在正式介绍之前,你需要了解约束,如果你熟练运用autolayout或者Masonry这等玩意儿写约束,那么你就可以轻松理解下面的讲述了。如果你意识到这两个东东不认识你,那么爱学习的你要利用好网络,去搜索一下Masonry或autolayout,很多大虾讲过着玩俩玩意儿,也很好学,个人推荐Masonry。


下面开始干货

首先介绍UITableViewDelegate中的一个方法

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);

这货是iOS 7之后出现的,作用是返回一个估算的cell高度,如果你的应用支持iOS 7以及之后的版本,那就你就可以高枕无忧的愉快使用了。
按照正常的步骤来说,table view会先走heightForRow方法去获取高度,然后走cellForRow方法去初始化和赋值等。但是一旦你的代码中出现了这货,他俩的执行顺序就颠倒了,先执行estimatedHeightForRow,其次执行cellForRow,再执行heightForRow,可以见得heightForRow的作用被弱化了。
通过下面的讲解,你就会知道heightForRow岂止是被弱化了,这东西几乎要被抛弃了。


下面以一个最简单的例子讲解怎样去除恼人的高度计算(讲解、代码和demo基于Masonry)
分析一下,这个cell中包含两个label和一个view,一个是显示在上面的title label(“row : 2 …”),一个是显示在下面的detail label(“生活如此美好 …”),一个是最底下的灰线。

  1. cell中各个控件,先找出有上下关系的,如此cell中title label、detail label和灰线。
  2. 将有上下关系的控件的top和bottom约束好,例如这个cell中,title label在detail label上面距离其顶部x,detail label 在灰线上面,距离灰线顶部y。
  3. 最为关键的点:给最上面的title的top和最下面的灰线的bottom添加相对于父视图的约束
  4. 最后愉快的删除heightForRow并写上estimatedHeightForRowAtIndexPath方法,return一个你喜欢的数字(当然越接近真实值越好)
    • //label的高度就不需要操心了,因为它会根据内容的多少自适应,这也是之前计算label高度的关键
这里给出上面cell中三个控件的约束代码
 /**
        请仔细看两个控件之间以及它们和父视图的约束,主要是top和bottom之间的约束
        1、titleLab在上面,距离父视图上方和左边各10像素
        2、detailLab在titleLab下面,距离titleLab 8像素,左边和titleLab对齐,切底部距离bottomLine 10像素
        3、bottomLine在最下面,左右和底都和父视图对齐,高度为1
     Label是个好玩的东西,如果有文本,则label有高度,如果内容为空,则高度为0,我们就是利用了它们的这个特性来省区计算高度的步骤
     * 当然,为了使其能自适应高度,我们一般会把label的宽度约束死
     * 代码中重点约束已标注 “//重点”
     */

    [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.equalTo(self).offset(10);//重点
        make.right.equalTo(self).offset(-15);
    }];
    [self.detaiLab mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.titleLab);
        make.top.equalTo(self.titleLab.mas_bottom).offset(8);//重点
    }];
    [self.bottomLine mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.detaiLab.mas_bottom).offset(10);//重点
        make.bottom.left.right.equalTo(self); //重点
        make.height.mas_equalTo(1);
    }];

通过上面三个步骤,cell以及其中的三个控件的上下约束已经完成。现在给title label和detail label填充内容,它们的高度随文字自适应,那么cell的高度也会随着label的高度的改变而改变(因为它们之间的上下关系已经约束好了嘛)
这个时候estimatedHeightForRowAtIndexPath这货就该出场了,为什么呢?因为有了它和约束就不需要再去手动指定高度了啊(给cell中控件赋值完成的时候也就是其高度确定了的时候,如果heightForRow方法走之前能够确定这个cell的高度,那它的存在也就没有任何意义了,当然这里一定要在cellForRow这个方法中对控件赋值,这对于习惯在willDisplayCell中赋值的童鞋来说是个悲剧,不信你可以试试)~后知后觉了嘛?


运用这个方法省区高度计算最为核心的核心是:cell的top和bottom和其中控件之间的约束正确无误,否则会出现什么意想不到的问题我就不知道了~


内容就上面这些了,不知道我有没有讲清楚,也不知道你有没有心领神会和恍然大悟。有不理解的地方和讲得不对的地方,欢迎下方留言讨论。

时间已近凌晨两点,想想今天(周六)还要加班,赶紧去睡了,泪流满面的时间都没有~

demo地址:https://github.com/NSSONGMENG/TableDemo

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

iOS cell高度自适应 - 教你写出优雅的table view 的相关文章

  • 无法识别的选择器调用静态 iOS 库中的类别方法

    我正在使用一些第三方软件来帮助使用 Xcode 4 3 2 编写 iPad 应用程序 该软件是开源的 通常经过设置 因此其代码将与开发人员为应用程序编写的任何代码一起编译 因为我在很多地方使用该软件 所以我决定将其构建为 iOS 模拟器的静
  • SQL如何将两个日期之间一小时内的事件相加并显示在一行中

    我正在使用 C 和 SQL Server 2005 开发一份报告 我只需显示我们每小时获得的点击次数 桌子很大 输出应如下所示 Row Date Time Hit Count 1 07 05 2012 8 00 3 2 07 05 2012
  • CIAdditionCompositing 给出不正确的效果

    我正在尝试通过平均其他几个图像来创建图像 为了实现这一点 我首先将每个图像变暗 其系数等于我平均的图像数量 func darkenImage by multiplier CGFloat gt CIImage let divImage CII
  • 调用了 numberOfRowsInSection 但未调用 cellForRowAtIndexPath

    在我的表视图中节中的行数被调用两次但是cellForRowAtIndexPath不叫 我想在 tableView 中显示 Facebook 好友列表 如果 cellForRowAtIndexPath 调用我的问题就解决了 我在这里的数组中得
  • 是否可以在增强现实应用程序中使用自定义 iOS UI 元素(例如 UILabel)

    我想知道是否可以使用像这样的 UI 元素UIButton UILabel在带有 ARKit 的增强现实应用程序中 如果您也对 UIView 子类的透明度模式感兴趣 请尝试我的示例https github com erikhric ar me
  • 如何在rails3中渲染编辑视图并发布Flash消息

    在我的帐户控制器中 我想在保存更改后显示 渲染 redirect to 编辑视图并显示闪存通知 def update account Account find params id respond to do format if accoun
  • Android - API 请求

    我开发了一个应用程序 它也在 iPhone 上 问题出在 api 请求上 我为所有请求设置了超时 有时会出现 30 60 秒的中断 看起来这个应用程序执行了几个请求 然后就中断了 一直超时 大约 45 秒后一切正常 不知道是服务器问题还是安
  • 在 Swift 中使用 commitEditingStyle 动态删除 UITable 部分

    我正在处理一个无法解决的问题 我有一个来自客户数据库数组的名称表 每个客户在其他数据成员中都有一个名称属性 我可以成功删除某个部分中的行 但我不能删除该部分 当该部分中的最后一行被删除时 该部分必须消失 I got NSInternalIn
  • 如何在 SQLite 中替换字符串?

    如何更新具有以下内容的表列 var mobile 233KKFSDK3234 Documents Page jpg 并将其替换为 Documents Page jpg 在 SQLite 中 注意 所有文字 除了 Documents 是动态的
  • 以编程方式向 UIButton 标签添加阴影

    我试图向按钮标签添加 1px 黑色阴影 但没有成功 我试过这个 self setTitleShadowOffset CGSizeMake 0 1 但我得到 请求非结构或联合中的成员 setTitleShadowOffset 任何建议都会很棒
  • NSOperation 中委托的使用

    我正在尝试利用CLLocationManager in an NSOperation 作为其中的一部分 我需要能够startUpdatingLocation然后等到收到 CLLocation 后才完成操作 目前我已经完成了以下操作 但是委托
  • 无法添加钥匙串项目。使用 KeychainItemWrapper 更改标识符后出现错误 - 25299?

    我想用 KeychainItemWrapper 将 UUID 保存在钥匙串中 所以我在中添加以下方法MyKeychainManager m define keychain idenentify com myapp bundle1 void
  • 使用 UIKeyCommand 检测删除键

    任何人都知道如何使用检测 删除 键UIKeyCommand在 iOS 7 上 当人们在使用 Swift 时遇到问题时 我认为用 Objective C 和 Swift 编写一个小型的 完整的例子可能是一个很好的答案 请注意 Swift 没有
  • 无需 iPhone 6 Plus 即可预览 iOS 应用程序

    我已经在 Yosemite 中使用 iPhone 6 和 Quicktime 完成了 iOS 应用程序预览 视频 但我无法在 iTunes Connect 中为 iPhone 6 上传它 而且我没有 iPhone 6 设备 有没有办法在没有
  • PhoneGap 1.4 封装 Sencha Touch 2.X - 性能怎么样?

    我正在构建一个多平台平板电脑应用程序 仅使用其 Webview 使用 Phonegap 1 4 对其进行包装 然后使用 Sencha Touch 2 框架发挥我的魔力 我所说的多平台是指 iOS 5 X 和 Android 3 0 目前 到
  • 我如何从 iPhone 设备获取电子邮件历史记录..?

    friends 我想从我的 iPhone 访问电子邮件历史记录 并且还希望在收到新邮件时收到通知 如果可能的话 请向我提供源代码片段 Thanks 简而言之 使用任何已记录的 API 都是不可能的
  • 将捕获的图像精确裁剪为 AVCaptureVideoPreviewLayer 中的外观

    我有一个使用 AV Foundation 的照片应用程序 我使用 AVCaptureVideoPreviewLayer 设置了一个预览层 它占据了屏幕的上半部分 因此 当用户尝试拍照时 他们只能看到屏幕上半部分看到的内容 这很好用 但是当用
  • 断点条件错误

    我已经根据条件设置了断点 event name isEqualToString Some Name 这很好用 但是 当我尝试添加另一个带有条件的断点时 part name isEqualToString Some Value With A
  • 快速钥匙串更新只有在第二次尝试时才起作用

    您好 我在更新存储在钥匙串中的登录信息方面遇到了 iOS 钥匙串的一个非常奇怪的问题 因此 如果没有保存的凭据 则正确运行保存函数会保存登录信息 如果登录信息已存在并且用户更新了密码 则更新功能仅正确更新密码 但是 如果登录信息存在并且我尝
  • 进入后台时 Alamofire 请求卡住?

    我正在使用 Alamofire 调用 Web 服务 该服务需要相当长的时间才能加载 如果应用程序进入后台 当我返回应用程序时 我会被加载程序卡住 我想这是因为调用永远不会向我的完成处理程序返回任何内容 我该如何解决这个问题 您可以使用后台抓

随机推荐

  • https 自签名SSL证书

    介绍 TLS或称传输层安全性 xff0c 及其前身SSL xff08 代表安全套接字层 xff09 是用于将正常流量包装在受保护的加密包装中的Web协议 使用这种技术 xff0c 服务器可以在服务器和客户端之间安全地发送流量 xff0c 而
  • Gitlab安装及配置

    主要内容 xff1a 使用docker运行 gitlab xff1b 配置LDAP及邮箱 xff1b 配置管理员账号 xff1b 配置邮箱通知 xff1b 关闭用户注册 xff1b 安装 我们使用docker来安装Gitlab xff0c
  • windows 文件夹正在使用 “操作无法完成,因为其中的文件夹或文件已在另一程序中打开“ 解决办法

    解决办法 xff1a 右键状态栏 gt 任务管理器 gt 性能 gt 打开资源监视器 gt CPU gt 在 关联的句柄 处搜索被占用的文件夹名称 现象 解决办法 第1步 第2步 第3步 例如搜索 test 第4步 右键找到占用的程序 第5
  • Windows服务器更新服务的配置-client

    0x01 WSUS客户端 wsus客户端可以使windows的各种系统 windows7 8 10 server 无须安装任何软件 0x02 客户端配置 wsus客户端通过配置本地组策略来实现 运行中输入 xff1a gpedit msc
  • Anime4K:目前最热的开源实时动漫放大算法,Github上一周收获2600星!

    点击我爱计算机视觉标星 xff0c 更快获取CVML新技术 今天跟大家介绍一款动漫画面放大算法Anime4K xff0c 目前最热的开源 实时 视频动漫放大算法 https github com bloc97 Anime4K 一周内该库在G
  • 统计学:离散型和连续型随机变量的概率分布

    主要随机变量一览表 随机变量概率分布均值方差一般离散型变量 p x 的 表 公 式 或 者 图 x x p x x x 2 p x 二项分布 p x 61 C x n p x
  • Stata基本功能及其函数实现

    Stata简介 xff1a Stata使用简单 xff0c 功能强大 xff0c 是数据分析中常用的统计计量软件 本人使用的是Stata14 xff0c 如若需要 xff0c 可评论留言 xff01 1 Stata基本描述 1 1主窗口 如
  • MySQL安装过程问题:服务器名无效,发生系统错误 5 拒绝访问

    1 服务器名无效 安装好MySQL之后 xff0c 使用CMD系统命令程序 xff0c 输入命令启动MySQL xff0c 提示 服务器名无效 原因1 xff1a 服务器名字错误 解决方法 检查命令行中服务器名是否正确 xff0c MySQ
  • R语言基础画图/绘图/作图

    R语言基础画图 R语言免费且开源 xff0c 其强大和自由的画图功能 xff0c 深受广大学生和可视化工作人员喜爱 xff0c 这篇文章对如何使用R语言作基本的图形 xff0c 如直方图 xff0c 点图 xff0c 饼状图以及箱线图进行简
  • 【网站】IIS配置/搭建PHP环境的网站教程

    原文 xff1a https www fujieace com php iis html 今天一位群友想新搞一个万能门店小程序网站 xff0c 由于他的服务器上面已经存在了很多的老站 xff0c 用的IIS6 0服务 xff0c 现在这个网
  • MySQL数据库事务处理

    事务处理用于有效记录某机构感兴趣的业务活动 xff08 称为事务 xff09 的数据处理 xff08 例如销售 供货的定购或货币传输 xff09 通常 xff0c 联机事务处理 OLTP 系统执行大量的相对较小的事务 百度百科 事务处理是将
  • 神农尝百草---Windows环境下为Python3.X安装basemap

    basemap是matplolib的一个插件 xff0c 提供了许多将地理位置 xff08 如经度和纬度 xff09 转化为二维matplotlib图的方式 xff0c 是地图数据可视化的重要工具 本人Python是3 6版本 xff0c
  • 机器学习之朴素贝叶斯(NB)分类算法与Python实现

    朴素贝叶斯 xff08 Naive Bayesian xff09 是最为广泛使用的分类方法 xff0c 它以概率论为基础 xff0c 是基于贝叶斯定理和特征条件独立假设的分类方法 一 概述 1 简介2 条件概率与贝叶斯定理3 朴素贝叶斯分类
  • Python批量修改文件名

    工作中经常会遇到需要批量修改文件名的情况 xff0c 比如 xff1a 有这样一个文件夹 xff0c 里面是249个国家的国家 xff0c 按照ISO 3166 1标准中的国家二位简称进行命名 xff1a 现在面临这样的需求 xff0c 需
  • Excel实战:时间转换、字符串拆分和多条件判断

    1 概述 1 1案例 有如下通话记录数据 xff0c 包括主叫 被叫和通话时长 43 43 43 43 43 span class hljs string date caller callee duration span 43 43 43
  • Vue3 script setup 语法糖(升级版)

    序 xff1a 使用了vue3后发现变量每次都必须return xff0c 不免很麻烦 xff0c 所以在vue3 2添加了script setup 语法糖 xff0c 本次修改主要从以下5个方面做了修改 1 SSR xff1a 服务端渲染
  • 基于kurento-media-server 搭建流媒体服务器

    关于webrtc 是做什么的 xff0c 网上有很多介绍就不多说了 我的需求是通过webrtc的开源实现 xff0c 搭建本地的流媒体服务器 xff0c 进行rtsp视频流转发 xff0c 如果可以再叠加一些机器视觉的内容 本篇内容主要解决
  • OSPF 路由协议基础实验

    实验介绍 关于本实验 开放式最短路径优先 OSPF xff08 Open Shortest Path First xff09 是 IETF 组织开发的一个基于链路状态的内部网关协议 xff08 Interior Gateway Protoc
  • Flutter错误和解决办法

    Flutter使用遇到的问题 xff1a 1 xff0c Expected a key while parsing a block mapping Error on line 30 column 4 of pubspec yaml Expe
  • iOS cell高度自适应 - 教你写出优雅的table view

    作为一个iOS开发者 xff0c 自然少不了了table view打交道 xff0c table view中最令人头疼的是各种cell的高度计算了 xff0c 虽然技术上并不难 xff0c 但是对于自定义cell来说一旦控件比较多 xff0