如何标准化 UILabel 的不同截断点字符?

How can I standardize the the varying truncating dot characters of UILabel?

我有一个 plist 文件,我对其进行解码以将数据加载到我的应用程序中。 此 plist 文件包含映射到 UILabel 文本 属性.

的字符串类型值

我注意到标签中文本的截断行为并不总是相同的。 更具体地说,截断文本时添加的三个点与我的预期相反,是两种:一种是...,另一种是⋯,在这个[=中似乎是这个unicode字符12=].

我检查了 UILabel 的属性设置,但找不到与此行为相关的任何设置。

有没有其他人遇到过这个问题并将截断字符标准化为...

这是描述上述问题的图片。两个标签都有 2 行,并且在第一行和第二行文本之间插入了换行符。我正在 post 对这张图片进行 link,因为显然我没有足够的声誉来 post 图片。

varying truncating characters of UILabel

IMO 这是 UILabel 中的一个错误,可能值得打开一个关于它的反馈。

TL;DR:我建议使用 TTTAttributedLabel


冗长的回答,因为这是一个非常有趣的问题:

UILabel 根据所使用的语言脚本使用不同的省略号运行。正如您所注意到的,对于大多数脚本,它们使用水平省略号 () 或非常相似的东西。但是对于中文、日文和韩文 (CJK),他们使用 MIDLINE HORIZONTAL ELLIPSIS (),或者再次使用非常相似的东西。我发现的另一个例外是缅甸语,它使用了三个我不认识的圆圈。

在我的测试中,使用了以下所有语言 :拉丁语、西里尔语、孟加拉语、阿拉伯语、希伯来语、印地语、泰语、卡纳达语、尼泊尔语和蒙古语(我开玩笑。iOS 不能t layout Mongolian. 没有人可以layout Mongolian,但它仍然使用)。 UILabel 甚至对老挝语使用 ,尽管我认为 是专门用于此的,但我想最终一切都变成了拉丁语。

UILabel 对 CJK 和缅甸语如此聪明的问题在于它通过查看第一个被删除的字符来决定专门使用哪个字符。它认为 SPACE 是拉丁语(或者至少不是“特殊”)。

那怎么办?我的建议可能是使用 TTTAttributedLabel,因为它可以让你配置 t运行cation 字符,更重要的是,它是开源的,所以如果它没有按照你想要的方式工作,你可以修复它。

第二种选择是使用 How to change truncate characters in UILabel? 中描述的技术手动编辑文本 运行。可能有更好的方法来使用 CTFrameGetVisibleStringRange 而不是不断缩小字符串直到它适合,但我不知道这是否值得付出努力。 (如果该路径听起来有用,我可能会写出一些有用的东西。这可能不值得麻烦。)

我知道的最后一个选择是用“等效”的 CJK 字符替换 SPACE 字符。我发现最接近的是 HANGUL FILLER (U+3164),但我不喜欢它。太宽了,我估计韩语读起来会不舒服(但我很少尝试读韩语,所以我这里可能是错的):

与SPACE:안녕하세요

有 FILLER:안녕ㅤ하세요

还有 HALFWIDTH HANGUL FILLER (U+FFA0),更好,但 UILabel 似乎使它的宽度为零(这可能是字体问题,所以也许值得一试):

与SPACE:안녕하세요

HALF:안녕ᅠ하세요

let string = "안녕 하세요"
let filler = "\u{3164}"
label.text = string.replacingOccurrences(of: " ", with: filler)

OTOH,如果您使用任何其他非 CJK 字符(例如拉丁标点符号或阿拉伯数字),您可能 运行 会遇到同样的问题。所以这个解决方案可能无法扩展。并且你应该确保 Voice Over 正确地忽略它。