Detecting Truncation in UITextViews

Do your text views show…?

Alex Persian
Dec 10, 2019 · 4 min read

One of the challenges you might encounter when working with UITextViews is that they don’t provide a straightforward way to detect whether or not they are displaying truncated text.

With a UILabel you can check for truncation by calculating the size of the text within the label and comparing that with the bounds of the label itself. If the text extends beyond the bounds then it’s being displayed as truncated.

The challenge with UITextView is that, by design, it can hold text that is far larger than its bounds.

This is the essence of how a scrolling text view operates. That feature breaks our ability to quickly check for truncation, so to begin with, we need to work with a textview that has scrolling disabled.


Solution

This is where some knowledge on TextKit and how iOS lays out and manipulates rendered text comes in handy. I highly recommend reading up on the TextKit official documentation, along with this excellent write-up by the folks over at objc.io.

From here on, I will assume you have at least a cursory understanding of text layout within iOS.

Since we can’t rely only on the bounds of the UITextView for making this check, we have to lean on the NSLayoutManager within the textview itself.

So, if we have a textview that is displaying truncated text like below then we can use the following snippet to detect that.

Example of tail truncation

What are we doing here exactly? Well, NSLayoutManager works with line fragments for laying out text. These are essentially rectangles that define the bounds for each line of text.

Again, the objc.io article goes into far more depth than I can here, but the gist is that using that concept of line fragments, we can ask the layout manager to search through them to find the truncation glyph we care about (…).

If it’s found, we can stop the traversal and know that our text is being rendered in a truncated fashion.

Side-note: Why can’t we just search the textContainer.text property for the ... character?

Well, under the hood, the textContainer has no concept of the truncation glyph existing at all. That work is done a layer above by the NSLayoutManager before the text is finally rendered to the screen.

This solution on its own will work great for detecting tail truncation. But what if the textview just isn’t wide enough or tall enough to render all of the text?

For that, we will need to inspect the text container’s characters and glyphs to compare them. An example of such a textview is displayed below, along with the following snippet detailing how the detection works.

Example of word-wrap truncation

This should now cover both cases where the lineBreakMode is set to byTruncatingTail along with byCharWrapping/byWordWrapping. You can find the full gist of this solution here.


Conclusion

As you can see, it’s not very straightforward to detect whether or not some text is displayed in a truncated fashion. This is likely by design from Apple since it would open up a ton of edge cases, and goes somewhat against the purpose of UITextView.

Even with the solution above, it’s only possible to detect truncation reliably when using the three lineBreakMode settings listed above. It also requires that the textview being inspected has scrolling disabled.

So, use at your own discretion. In my case, the need for this behavior arose from a product requirement where we were displaying shortened comments and we wanted to allow for inline expansion behavior.

Also, I would like to give a huge shoutout to Dave DeLong as he sat with me for a long time to help figure out this solution, and most of the credit for it working properly goes to him.

Anyway, I hope this has helped you out or at least been an informative read. Please leave a comment below if you find an error in my solution or if you have a different approach to this that worked for you. Cheers!


Better Programming

Advice for programmers.

Alex Persian

Written by

iOS engineer @ Spotify

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade