1

I have a plist file which I decode to load data onto my application. This plist file contains String type values that gets mapped to UILabel's text property.

I noticed that the truncating behavior of the text in the label is not always the same. To be more specific, the three dots that are added when the text is truncated are, as opposed to my expectation, two kinds: one being ... and the other being ⋯ which appears to be this unicode character in this link.

I checked UILabel's attribute settings but I was unable to find any settings related to this behavior.

Has anyone else experienced this problem and standardized the truncating character to be ...?

Here is the image describing the problem mentioned above. Both labels have 2 lines and have new line escape character inserted between the first line and the second line of text. I am posting a link to this image because apparently I don't have enough reputation to post an image.

varying truncating characters of UILabel

Eric Jang
  • 13
  • 5
  • I expect the truncation character to generally be … (https://www.compart.com/en/unicode/U+2026), rather than three dots. Is it possible that it's using a center-aligned version because the truncated text is Korean rather than Latin? This is a very interesting case; do you have some code that demonstrates it? Is it just loading Korean into a UILabel that requires truncation, or is it more complex than that? (Since the other text is Korean, this seems unlikely; what is the difference between the two?) – Rob Napier Feb 12 '21 at 04:08
  • Regarding to your question about the loading of the text to UILabel, the text is assigned to UILabel inside custom UICollectionViewCell when the cell is being dequeued from the collection view's data source. This is just a simple assignment of string to UILabel. After numerous tests with varying combination of texts, I found that that the center-aligned dots appear if consecutive Korean characters are placed where the text becomes truncated. – Eric Jang Feb 12 '21 at 13:11
  • For example, "placeholder text placeholder text 안녕하세요" produces center-aligned dots because the location where the text is truncated has **consecutive Korean Characters without any whitespace** (Referring to the "안녕하세요" part). On the other hand, however, if the location where the text is truncated has whitespace, the truncation produces the `...` version. An example of this would be "placeholder text placeholder text 안녕 하세요".(The only difference between this example and the first example is the whitespace between "안녕" and "하세요") – Eric Jang Feb 12 '21 at 13:46
  • Here I made an image describing the two cases explained above. This should clarify what I mean by consecutive Korean characters and with or without whitespace at the point of truncation. https://user-images.githubusercontent.com/46217844/107775492-ae755300-6d83-11eb-9385-840553f032ca.png Plus I'd like to thank you for helping me solving this problem. Honestly I didn't think there was any difference between the two, but your suggestion helped me to keep on going. Huge thanks to you from South Korea. @Rob – Eric Jang Feb 12 '21 at 13:50

1 Answers1

0

IMO this is a bug in UILabel, and it may be worth opening a Feedback about it.

TL;DR: I recommend using TTTAttributedLabel.


Long-winded answer, because this was such an interesting question:

UILabel uses a different ellipsis based on the language script being truncated. As you've noticed, for most scripts, they use HORIZONTAL ELLIPSIS (), or something very similar. But for Chinese, Japanese, and Korean (CJK), they use MIDLINE HORIZONTAL ELLIPSIS (), or again, something very similar. The only other exception I've found is Burmese, which uses three circles that I don't recognize.

In my tests, all the following used : Latin, Cyrillic, Bengali, Arabic, Hebrew, Hindi, Thai, Kannada, Nepali, and Mongolian (I kid. iOS can't layout Mongolian. Nobody can layout Mongolian, but it still uses ). UILabel even uses for Lao, even though I thought was specifically for that, but I guess eventually everything becomes Latin.

The problem with UILabel being so clever for CJK and Burmese is that it decides what character to use exclusively by looking at the first character being removed. And it thinks SPACE is Latin (or at least not "special").

So what to do? My recommendation is probably to use TTTAttributedLabel, since it lets you configure the truncation character, and more importantly, is open source so you can fix it if it's not working the way you want.

The second option would be to truncate the text by hand using techniques like the one described in How to change truncate characters in UILabel?. There are probably better ways to do it using CTFrameGetVisibleStringRange instead of constantly shrinking the string until it fits, but I don't know if it's worth the effort. (If that path sounds useful, I could probably write up something that does it. It's just probably not worth the trouble.)

And the final option I know is to replace the SPACE character with an "equivalent" CJK character. The closest I've found that works is HANGUL FILLER (U+3164), but I don't like it. It's too wide, and I expect that it will make Korean uncomfortable to read (but I rarely try to read Korean, so I may be wrong here):

With SPACE: 안녕 하세요

With FILLER: 안녕ㅤ하세요

There's also HALFWIDTH HANGUL FILLER (U+FFA0), which is better, but UILabel seems to make it zero width (this may be a font issue, so maybe worth trying):

With SPACE: 안녕 하세요

With HALF: 안녕ᅠ하세요

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

OTOH, you may run into the same problem if you use any other non-CJK characters, like Latin punctuation or Arabic numerals. So this solution may not scale. And you should make sure that Voice Over properly ignores it.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610