问题概述

使用的是”预估行高+自动布局“的方法实现动态行高(适用于 iOS7.0 以后系统)。

预估行高:

self.gTV.estimatedRowHeight = 90;
self.gTV.rowHeight = UITableViewAutomaticDimension;

自动布局,又叫 autolayout,为了使文本可以多行显示,需要保证如下设置:

  • 设置 label 的 numberoflines 为 0
  • 对 label 进行上左下右的完整约束

在项目实现过程中,遇到了文本内容被截断最后一行一小部分,无法完全显示的问题。

为了复现项目中遇到的此问题并找到原因,做了如下尝试:

一、新建工程

新建工程测试,cell上下约束完备,底部高度约束 contentLblBtmCon 为>=9,优先级默认1000。发现预估行高是正常的。

效果如下:

二、尝试复现问题

隐藏系统cell分割线:self.gTV.separatorStyle = UITableViewCellSeparatorStyleNone;

同时,在自定义cell中重写 setFrame方法实现分割线效果,结果发现文字开始显示不全了!

- (void)setFrame:(CGRect)frame{
frame.size.height -= 8;
[super setFrame:frame];
}

约束报错如下:

2021-02-07 14:56:37.416314+0800 DynamicCellHeightTest[60202:8764494] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6000033a5810 UILabel:0x7f898d0072c0.height == 21 (active)>",
"<NSLayoutConstraint:0x6000033a59f0 UILabel:0x7f898d016da0.height >= 20.5 (active)>",
"<NSLayoutConstraint:0x6000033df2a0 V:|-(16)-[UILabel:0x7f898d0072c0] (active, names: '|':UITableViewCellContentView:0x7f898d0061f0 )>",
"<NSLayoutConstraint:0x6000033df340 V:[UILabel:0x7f898d0072c0]-(NSSpace(8))-[UILabel:0x7f898d016da0] (active)>",
"<NSLayoutConstraint:0x6000033df430 V:[UILabel:0x7f898d016da0]-(>=9)-| (active, names: '|':UITableViewCellContentView:0x7f898d0061f0 )>",
"<NSLayoutConstraint:0x6000033ddb80 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f898d0061f0.height == 86 (active)>"
) Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000033a59f0 UILabel:0x7f898d016da0.height >= 20.5 (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

通过 log 可知,内容 label 的高度约束被舍弃了,因此会出现内容显示不全的问题。模拟器运行效果:

尝试解决

修改contentLblBtmCon优先级为High(750)

结果还是不太行:

修改contentLblBtmCon优先级为Low(250)

效果如下:

可见,此时内容可以显示全了,Xcode 也不报错了。但是内容距离 cell 底部的距离太小了,并没有大于 9。猜测:这个底部约束因为优先级是Low,所以被系统舍弃,使得内容可以显示完整,同时导致内容距离 cell 底部的距离太小。

但是,当我尝试设置底部约束的为 >= 9+8=17,再运行,居然就是我想要的效果:

分析:系统先在 setFrame 生效之前,对 cell 内的上下所有约束进行行高预估。计算拿出结果后缓存。在 cell 显示之前,setFrame 生效,此时,cell 在之前预估行高的基础上,根据约束重新布局,舍弃了内容 label 的高度约束,导致内容显示不全。

当我们把底部约束的优先级降低到 Low 时,cell 在之前预估行高的基础上,根据约束重新布局,舍弃的就是低优先级的底部约束了,因此才能看到低优先级底部约束开始生效,后来因 setFrame 减小了高度,导致底部间隔变小的效果。此时,我们将计就计,把底部约束增加 cell 间隔高度(8),即可得出我们想要的效果!

小结

重写 cell 的 setFrame 方法改变 cell 高度来实现分割线效果时,可能导致多行 label 显示不全,此时,可以通过降低底部约束优先级为 Low + 增加底部约束的值(cell 间距),来实现想要的文本多行显示效果。

其他解决思路

当然,为了实现行分割线效果,我们也可以在自定义 cell 的底部手动添加一个 UIView 子视图,高度设置为 cell 间隔高度,颜色改为与 UITableview 背景色一致(与 cell 背景色不同),也能达到同样的效果。这种方法就不会因为重写 cell 的 setFrame 方法导致多行文字显示不全了。但是,当 cell 有选中效果或左滑删除效果时,相关效果就不是很好了,因为分隔线 View 属于 cell 的一部分被一起选中或移动,看起来效果有点不太好。

好了,这次的探索就到这里了。下面附上测试用的源代码,欢迎 star!3Q!

源代码地址

OCDailyTests/DynamicCellHeightTest

Cell 动态行高文字显示不全问题探索的更多相关文章

  1. 对tableView三种计算动态行高方法的分析

    tableView是一个神奇的东西,可以这么说,就算是一个初学者如果能把tableView玩的很6,那编一般的iOS的需求都问题不大了.tableView是日常开发中用烂了的控件,但是关于tableV ...

  2. [置顶] echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐)

    echarts x轴标签文字过多导致显示不全 如图: 解决办法1:xAxis.axisLabel 属性 axisLabel的类型是object ,主要作用是:坐标轴刻度标签的相关设置.(当然yAxis ...

  3. tableView计算动态行高的总结

    研究tableView怎么计算动态行高研究了两天一直还不太会,今天最终做出来了想要的效果. 首先.我在网上搜集了非常多资料,各种大神的总结,然后開始看.研究.试验,基本思路都是一样的. 1.一定要将l ...

  4. echarts x轴文字显示不全(解决方案)

    echarts x轴标签文字过多导致显示不全 如图: 解决办法1:xAxis.axisLabel 属性 axisLabel的类型是object ,主要作用是:坐标轴刻度标签的相关设置.(当然yAxis ...

  5. echarts x轴文字显示不全解决办法

    标题:echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐):http://blog.csdn.net/kebi007/article/details/68488694

  6. UItableView动态行高 用这两句实现(可以自己计算数据来实现,一般在model中计算)

    // 动态行高 self.tableView.rowHeight = UITableViewAutomaticDimension; // 预估行高 self.tableView.estimatedRo ...

  7. iOS开发——UI进阶篇(三)自定义不等高cell,如何拿到cell的行高,自动计算cell高度,(有配图,无配图)微博案例

    一.纯代码自定义不等高cell 废话不多说,直接来看下面这个例子先来看下微博的最终效果 首先创建一个继承UITableViewController的控制器@interface ViewControll ...

  8. echarts x轴坐标文字显示不全

    在echarts中应用柱状图或者折线图时,当数据量过多的时候,X轴的坐标就会显示不全(如下图图一),在ECharts图表组件内部有一个机制,用于统计xAxis坐标刻度的个数和图表宽度,从而会自动调整刻 ...

  9. confluence导出pdf 文字显示不全

    当使用confluence编辑页面时,当一行的文字过多,且中间没什么逗号分隔时,有时会出现导出的pdf文件中,这一行显示的文字不全的情况. 如: 很明显费用的费字没有显示完全,且后面还有其他的字. 可 ...

随机推荐

  1. 安装newman error:package exports for 'c:\nmp\node_modules\newman\node_module 解决办法

    一.场景描述: 通过npm安装newman时,一直失败. 尝试了很多安装命令: npm install -g newman npm install -g newman --registry=http: ...

  2. LeetCode543.二叉树的直径

    题目 1 class Solution { 2 public: 3 int minimum = INT_MIN; 4 vector<int>res; 5 int diameterOfBin ...

  3. [Usaco 2012 Feb]Nearby Cows

    题目描述 FJ发现他的牛经常跑到附近的草地去吃草,FJ准备给每个草地种足够的草供这个草地以及附近草地的奶牛来吃.FJ有N个草地(1<=N<=100000),有N-1条双向道路连接这些草地, ...

  4. E1.获取Elixir/Erlang版本信息

    E1.获取Elixir/Erlang版本信息 获取Elixir版本 直接在shel中打开iex (interactive shell),就可以查到具体的版本信息: iex Erlang/OTP 22 ...

  5. Wi-Fi IoT套件连PCF8563实现电子钟功能

    首先跟同样新入手单片机开发的小伙伴分享一点I2C通信的知识.我估计大部分入手开发板的小伙伴都有一定程序开发的能力,但是底层开发可能是新接触,我看有的小伙伴配置开发环境都有障碍,其实并不是多复杂,只是首 ...

  6. python系统监控及邮件发送

    python系统监控及邮件发送   #psutil模块是一个跨平台库,能轻松实现获取系统运行的进程和系统利用率   import psutil                              ...

  7. 关于Java客户端连接虚拟机中的Kafka时,无法发送、接收消息的问题

    kafka通过控制台模拟消息发送和消息接收正常,但是通过javaAPI操作生产者发送消息不成功 消费者接收不到数据解决方案? 1.问题排查 (1)首先通过在服务器上使用命令行来模拟生产.消费数据,发现 ...

  8. 手淘架构组最新实践 | iOS基于静态库插桩的⼆进制重排启动优化 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 编译期插桩

    抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% 原创 Leo 字节跳动技术团队 2019-08-09 https://mp.weixin.qq.com/s/Drmmx5JtjG ...

  9. 【LinuxShell】ps 命令浅析

    前言 Linux上查看进程状态最常用的命令,本文对 ps 命令参数以及状态做一下简单介绍. 参数 ps a 显示现行终端机下的所有程序,包括其他用户的程序. ps -A 显示所有程序. ps c 列出 ...

  10. CAP理论解读

    经历过技术面试的小伙伴想必对这个两个概念已经再熟悉不过了! 我当年参加面试的时候,不夸张地说,只要问到分布式相关的内容,面试官几乎是必定会问这两个分布式相关的理论. 并且,这两个理论也可以说是小伙伴们 ...