iOS14与iOS13中firstLineHeadIndent第二行表现差异适配问题
iOS14下NSAttributedString项目符号列表兼容iOS13显示方案
在使用NSAttributedString构建带自定义数据的项目符号列表时,iOS14环境下第二行会出现额外缩进,无法匹配iOS13的显示效果,简化后的问题代码如下:
let full = NSMutableAttributedString() let ps1 = NSMutableParagraphStyle() ps1.firstLineHeadIndent = 10 full.append(NSAttributedString(string: "\u{2022}\t", attributes: [.paragraphStyle: ps1])) let ps2 = NSMutableParagraphStyle() full.append(NSAttributedString(string: "123", attributes: [.paragraphStyle: ps2])) let ps3 = NSMutableParagraphStyle() full.append(NSAttributedString(string: "\u{2029}", attributes: [.paragraphStyle: ps3])) let ps4 = NSMutableParagraphStyle() ps4.firstLineHeadIndent = 10 full.append(NSAttributedString(string: "\u{2022}\t", attributes: [.paragraphStyle: ps4])) let ps5 = NSMutableParagraphStyle() full.append(NSAttributedString(string: "456", attributes: [.paragraphStyle: ps5]))
问题原因
iOS14对NSParagraphStyle的解析逻辑进行了调整,拆分设置段落样式的方式(将项目符号、文本、换行符分别赋予独立段落样式)会导致后续文本继承意外的缩进属性,或者段落边界的样式解析出现不一致,从而产生额外缩进。
解决方法
统一每个列表项的段落样式,同时配置firstLineHeadIndent和headIndent保持一致,并设置制表符的对齐位置,确保iOS14和iOS13的显示效果统一:
let full = NSMutableAttributedString() // 配置列表项通用段落样式 let listParagraphStyle = NSMutableParagraphStyle() listParagraphStyle.firstLineHeadIndent = 10 listParagraphStyle.headIndent = 10 // 确保后续行与首行缩进一致,iOS14必须设置 // 设置制表符位置,匹配首行缩进值,让项目符号后的文本正确对齐 listParagraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: 10)] // 添加第一个列表项(项目符号+制表符+文本+换行符) full.append(NSAttributedString(string: "\u{2022}\t123\u{2029}", attributes: [.paragraphStyle: listParagraphStyle])) // 添加第二个列表项 full.append(NSAttributedString(string: "\u{2022}\t456", attributes: [.paragraphStyle: listParagraphStyle]))
额外说明
- 不要将列表项的组成部分(符号、文本、换行)拆分为多个独立的
NSAttributedString并设置不同段落样式,统一的段落样式能避免系统版本间的解析差异。 - 如果不需要制表符,也可以直接计算项目符号的宽度,将
firstLineHeadIndent和headIndent设置为该宽度,然后直接拼接符号和文本,同样能实现一致效果。
内容的提问来源于stack exchange,提问作者Phuah Yee Keat
相关产品推荐
相关产品推荐

