iOS 包含行间距计算富文本size

在一次开发过程中,发现带有行间距的富文本计算高度,会有不准确的情况,富文本内容明明很长,但是计算出的高度只有不到20像素,导致整个cell的高度计算异常。

需求上是文字固定宽度,最多显示3行,超过3行尾部打点展示。按照需求设置了尾部打点 paraStyle.lineBreakMode = .byTruncatingTail, 然后计算富文本的大小。

let range = NSRange(location: 0, length: introduce.count)
var att = NSMutableAttributedString(string: introduce)
let paraStyle = NSMutableParagraphStyle()
paraStyle.lineSpacing = 4
att.addAttribute(.font, value: UIFont.systemFont(ofSize: 14), range: range)
// 计算内容高度
let screenWidth = UIScreen.main.bounds.size.width
let maxSzie = CGSizeMake(screenWidth-40, CGFLOAT_MAX)// 换行模式byClipping
paraStyle.lineBreakMode = .byTruncatingTail
att.addAttribute(.paragraphStyle, value: paraStyle, range: range)
size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).size
print("使用byTruncatingTail计算size ", size)

这时候算出来的size高度只有17像素,真实显示到屏幕上Label的高度是58像素。导致整体cell的高度计算错误。

后来发现先将换行模式改为paraStyle.lineBreakMode = .byWordWrapping 在计算高度是正确的。于是把所有的换行模式都逐个测试,看看到底是什么情况。


func getTextAttributed(_ introduce: String) -> NSAttributedString {let range = NSRange(location: 0, length: introduce.count)var att = NSMutableAttributedString(string: introduce)let paraStyle = NSMutableParagraphStyle()paraStyle.lineSpacing = 4att.addAttribute(.font, value: UIFont.systemFont(ofSize: 14), range: range)// 计算内容高度let screenWidth = UIScreen.main.bounds.size.widthlet maxSzie = CGSizeMake(screenWidth-40, CGFLOAT_MAX)// 换行模式byWordWrappingparaStyle.lineBreakMode = .byWordWrappingatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)var size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byWordWrapping计算size ", size)// 换行模式byCharWrappingparaStyle.lineBreakMode = .byCharWrappingatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byCharWrapping计算size ", size)// 换行模式byClippingparaStyle.lineBreakMode = .byClippingatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byClipping计算size ", size)// 换行模式byTruncatingHeadparaStyle.lineBreakMode = .byTruncatingHeadatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byTruncatingHead计算size ", size)// 换行模式byClippingparaStyle.lineBreakMode = .byTruncatingTailatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byTruncatingTail计算size ", size)// 换行模式byClippingparaStyle.lineBreakMode = .byTruncatingMiddleatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byTruncatingMiddle计算size ", size)return att
}

测试后发现,系统的5个枚举中,只有 byWordWrapping和byCharWrapping 计算准确,带有截断方式的case,计算都是错误的。

  • case byWordWrapping = 0 // Wrap at word boundaries, default
  • case byCharWrapping = 1 // Wrap at character boundaries
  • case byClipping = 2 // Simply clip
  • case byTruncatingHead = 3 // Truncate at head of line: "...wxyz"
  • case byTruncatingTail = 4 // Truncate at tail of line: "abcd..."
  • case byTruncatingMiddle = 5 // Truncate middle of line:  "ab...yz"

好吧,系统这个样子,我们也没有办法,最后采用的方式

  1. 先用 byWordWrapping 计算高度
  2.  高度计算完成,在修改换行模式,paraStyle.lineBreakMode = .byTruncatingTail 
  3. 返回富文本
func getTextAttributed(_ introduce: String) -> NSAttributedString {let range = NSRange(location: 0, length: introduce.count)let att = NSMutableAttributedString(string: introduce)let paraStyle = NSMutableParagraphStyle()paraStyle.lineSpacing = 4att.addAttribute(.font, value: UIFont.systemFont(ofSize: 14), range: range)// 计算内容高度let screenWidth = UIScreen.main.bounds.size.widthlet maxSzie = CGSizeMake(screenWidth-40, CGFLOAT_MAX)// 换行模式byWordWrappingparaStyle.lineBreakMode = .byWordWrappingatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)var size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).sizeprint("使用byWordWrapping计算size ", size)// 换行模式byTruncatingTailparaStyle.lineBreakMode = .byTruncatingTailatt.addAttribute(.paragraphStyle, value: paraStyle, range: range)// size = att.boundingRect(with: maxSzie, options: [.usesLineFragmentOrigin,.usesFontLeading], context: nil).size// print("使用byTruncatingTail计算size ", size)return att
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/437770.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年第一篇博客

这是2024年的第一篇博客,2023年笔者经历了一连串的生活、工作、学习上的转折和调整,跌跌撞撞时光飞逝,转眼间就踏着元旦的钟声步入了2024年,前思后想、辗转反侧、犹豫再三不知道从哪里开始博客新的篇章,这个问题坦诚说…

SRM系统有什么用?有哪些好用的SRM管理系统?

在当今激烈的市场竞争环境下,供应商管理作为企业供应链的重要组成部分,直接影响着企业的运营效率和成本控制。然而,在实际操作中,许多企业都会遇到不少痛点问题: 采购寻源信息不透明,过程合规性难把控供应…

【Linux】Linux权限的概念 -- 详解

一、Linux 中的用户 Linux 下有两种用户: 超级用户(root):可以在 Linux 系统下做任何事情,不受限制。普通用户:在 Linux 下做有限的事情。 超级用户的命令提示符是 “#”,普通用户的命令提示符…

《HTML 简易速速上手小册》第2章:HTML 的标签和元素(2024 最新版)

文章目录 2.1 文本格式化标签(🎩✨📜 网页的“时尚搭配师”)2.1.1 基础示例:一篇博客的格式化2.1.2 案例扩展一:产品介绍页面2.1.3 案例扩展二:个人简历 2.2 链接和锚点(&#x1f6a…

MySQL原理(一)架构组成(1)物理文件组成

目录 一、日志文件 1、错误日志 Error Log 1.1、作用: 1.2、开启关闭: 1.3、使用 2、二进制日志 Binary Log & Binary Log Index 2.1、作用: 2.2、开启关闭: 2.3、Binlog还有一些附加选项参数 (1&#x…

2024.1.28 GNSS 学习笔记

1.基于 地球自转改正卫地距 以及 伪距码偏差 重构定位方程: 先验残差计算公式如下所示: 2.观测值如何定权?权重如何确定? 每个卫星的轨钟精度以及电离层模型修正后的误差都有差异,所以我们不能简单的将各个观测值等权…

2023年全球监管机构针对金融违规行为的罚款激增

2023 年,全球金融监管机构(尤其是美国)的执法行动激增。一项分析涵盖了美国证券交易委员会 (SEC)、商品期货交易委员会 (CFTC)、英国金融行为监管局 (FCA) 以及法国、德国、荷兰和新加坡等监管机构实施的处罚。调查结果描绘了一幅令人担忧的画…

国企(或事业单位)IT行业必考证书——软考

计算机技术与软件专业技术资格(水平)考试(简称“软考”)是原中国计算机软件专业技术资格和水平考试的完善与发展。计算机技术与软件专业技术资格(水平)考试是由国家人力资源和社会保障部、工业和信息化部领…

Pandas.Series.prod() 乘积(累乘积) 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本: 本文基于 pandas2.2.0 编写。 关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。 传送门: Pandas API参考目录 传送门: Pandas 版本更新及新特性 传送门&…

2024年【氧化工艺】报名考试及氧化工艺模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 2024年氧化工艺报名考试为正在备考氧化工艺操作证的学员准备的理论考试专题,每个月更新的氧化工艺模拟考试祝您顺利通过氧化工艺考试。 1、【单选题】 我国工业企业噪声卫生标准采用()。( A …

【安装指南】HBuilder X 下载、安装详细教程

目录 🌺1. 概述 🌻2. HBuilder X 安装包下载 🌼3. 安装详细教程 🌺1. 概述 HBuilder X 是一款由DCloud开发的基于Electron框架的集成开发环境(IDE),主要用于Web和移动应用程序的开发。以下是…

QT tcp与udp网络通信以及定时器的使用 (7)

QT tcp与udp网络通信以及定时器的使用 文章目录 QT tcp与udp网络通信以及定时器的使用1、QT网络与通信简单介绍2、QT TCP通信1、 服务器的流程2、 客户端的流程3、服务器的编写4、客户端的编写 3、QT UDP通信1、客户端流程2、客户端编写3、UDP广播4、UDP组播 4、定时器的用法1、…