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.mzph.cn/news/654072.shtml

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

相关文章

FPGA高端项目:Xilinx Zynq7020系列FPGA多路视频拼接 工程解决方案 提供6套工程源码和技术支持

目录 1、前言版本更新说明给读者的一封信FPGA就业高端项目培训计划免责声明 2、相关方案推荐我已有的FPGA视频拼接叠加融合方案本方案在Xilinx Kintex7 系列FPGA上的应用本方案在Xilinx Artix7 系列FPGA上的应用 3、设计思路框架视频源选择ov5640 i2c配置及采集动态彩条多路视频…

精通Python第13篇—数据之光:Pyecharts旭日图的魔法舞台

文章目录 引言准备工作绘制基本旭日图调整颜色和样式添加交互功能定制标签和标签格式嵌套层级数据高级样式与自定义进阶主题:动态旭日图数据源扩展:外部JSON文件总结 引言 数据可视化在现代编程中扮演着重要的角色,而Pyecharts是Python中一个…

黑群晖使用SynologyDrive同步家庭和公司电脑文件

文章目录 前言一、黑群晖安装SynologyDrive服务二、樱花frp内网穿透2.1、创建一个隧道2.2、在群晖里面下载、安装、开启樱花frp 三、本地电脑安装SynologyDrive 前言 最近看b站学习视频,发现里面老师喜欢文件都是使用坚果云同步到云盘里面,以前我是瞧不…

OpenHarmony—仅允许在表达式中使用typeof运算符

规则:arkts-no-type-query 级别:错误 ArkTS仅支持在表达式中使用typeof运算符,不允许使用typeof作为类型。 TypeScript let n1 42; let s1 foo; console.log(typeof n1); // number console.log(typeof s1); // string let n2: typeof …

Nuget包缓存存放位置迁移

一、背景 默认情况下,NuGet会将项目中使用的包缓存到C盘,随着项目开发积累nuget包越来越多,这会逐渐挤占大量C盘空间,所以我们可以将nuget包缓存位置指定到其他盘中存放。 二、软件环境 win10、vs2022 三、查看当前缓存存放位…

亚信安慧AntDB打造开放创新的数据库生态

在当今信息化快速发展的时代背景下,亚信安慧AntDB作为一种新兴的DBMS,以其核心优势引起了行业内的广泛关注。它基于具有广泛全球影响力和繁荣社区支持的PostgreSQL(PG)内核,继承了PG的开放性与生态活力,同时在性能和稳定性方面进行…

【C++】引用、内联函数、auto关键字等

前言:在前面我们讲解了C入门基础的一些学习例如命名空间、缺省参数、函数重载等。今天我们将进一步的学习,跟着博主的脚步再次往前迈一步吧。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C学习…

万字长文扫盲JUC基础

文章源码地址 文章目录 JUC概述什么是JUC线程和进程的概念进程和线程线程的状态wait和sleep并发和并行管程monitor用户线程与守护线程 Lock接口复习Synchronizedsyschronized卖票案例多线程编程步骤 什么是Lock接口Lock接口的介绍Lock实现可重入锁实现卖票案例 线程间通信案例…

从云计算到物联网:虚拟化技术的演变与嵌入式系统的融合

文章目录 一、硬件性能提升:摩尔定律与嵌入式虚拟化二、CPU多核技术:为嵌入式虚拟化提供支持三、业务负载整合:嵌入式虚拟化的核心需求四、降低硬件成本:虚拟化技术的经济效益五、软件重用与移植:虚拟化技术的优势六、…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏4(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言源码制作系统简单绘制制作系统面板UI斧头素材代码控制工具栏操作制作石斧 完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇…

C#用DateTime.Now.ToString方法将日期格式化为指定格式

目录 一、DateTime.Now.ToString方法 二、实例 一、DateTime.Now.ToString方法 调用DateTime对象的ToString方法可以将当前DateTime对象的值转换为其等效的字符串表示形式,而且ToString方法提供了重载,可以在ToString方法中添加不同的参数,…

JAVA编程语言单词汇总

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发,并在 1995 年正式推出。后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Ora…

Android 基础技术——Bitmap

笔者希望做一个系列,整理 Android 基础技术,本章是关于 Bitmap Bitmap 内存如何计算 占用内存 宽 * 缩放比例 * 高 * 缩放比例 * 每个像素所占字节 缩放比例 设备dpi/图片所在目录的dpi Bitmap加载优化?不改变图片质量的情况下怎么优化&am…

【一竞技DOTA2】Blacklist战队官宣租借Palos参加ESL伯明翰预选赛

1、Blacklist战队官宣租借Palos参加ESL伯明翰站最终预选赛。Palos自2022年2月份以来一直效力于同为东南亚赛区的Execration战队,这次租借是替补前不久刚刚离队的Raven。 2、俄罗斯未来运动会最近官宣nouns战队因故退出。另外还有Neon、Nigma,Entity&…

【Linux】第三十九站:可重入函数、volatile、SIGCHLD信号

文章目录 一、可重入函数二、volatile三、SIGCHLD信号 一、可重入函数 如下图所示,当我们进行链表的头插的时候,我们刚刚执行完第一条语句的时候,突然收到一个信号,然后我们这个信号的自定义捕捉方法中,正好还有一个头…

“值得一试的六个浏览器扩展推荐|让你的上网更加便捷和有趣!”

iTab新标签页(免费ChatGPT) iTab是新一代组件式标签页的首创者,简洁美观高效无广,是您打造个人学习工作台的浏览器必备插件。 详情请见: iTab新标签页(免费ChatGPT) - Microsoft Edge Addons AdGuard 广告拦截器 AdGuard 广告拦截器可有效的…

GD32移植FreeRTOS+CLI过程记录

背景 之前我只在STM32F0上基于HAL库和CubeMX移植FreeRTOS,但最近发现国产化替代热潮正盛,许多项目都有国产化器件指标,而且国产单片机确实比意法的便宜,所以也买了块兆易创新的GD32F303开发板,试一试它的优劣。虽然GD…

【Web前端实操17】导航栏效果——滑动门

滑动门 定义: 类似于这种: 滑到导航栏的某一项就会出现相应的画面,里面有对应的画面出现。 箭头图标操作和引用: 像一些图标,如果需要的话,可以找字体图标,比如阿里巴巴矢量图标库:iconfont-阿里巴巴矢量图标库 选择一个——>添加至购物车——>下载代码 因…

Facebook的智能时代:AI技术在社交中的崛起

随着科技的快速发展,人工智能(AI)技术已经深刻改变了我们的生活方方面面,而社交媒体领域也不例外。在这个信息爆炸的时代,Facebook正以令人瞩目的速度推动着AI技术在社交领域的崛起。本文将深入探讨Facebook如何在智能…

STM32控制DS18B20温度传感器获取温度

时间记录:2024/1/28 一、DS18B20温度传感器介绍 (1)测温范围-55℃~125℃,在-10℃到85℃范围内误差为0.4 (2)返回的温度数据为16位二进制数据 (3)STM32和DS18B20通信使用单总线协议…