Doing UITextView layout in advance and in the background

Short version: Is it possible to do the expensive parts of setting UITextView attributedText on a background queue in advance of the UITextView main thread setup?

Long version: Setting attributedText on UITextView is expensive, and UILabel is not an option for us. Is there a way to create a text container and layout manager ourselves in order to perform the expensive work on another queue in advance of setting up the UITextView? Ideally we wouldn’t need to have the layout manager draw a bitmap that we show instead of the UITextView altogether. We’re currently calling the layout manager’s ensureLayout(..) function on a background queue but not seeing an improvement in the main thread performance of setting the attributedText on the UITextView. Does ensureLayout(..) not compute and cache the layout work? Or is the layout work not the expensive part of setting attributed text?

Replies

Keep in mind that all UIKit APIs, including those offered by TextKit and UIFoundation, are not thread safe, and thus are not designed to be invoked from a background thread.

If you're not interested in having UITextView draw the bitmaps containing the rendered glyphs for its underlying text storage, it's perfectly possible to build a UITextView equivalent (perhaps one with thread safety and locking mechanisms, if you find the need to parallelize layout in your application) using just UIKit and TextKit APIs.

You can use NSTextLayoutManager, for instance, for all text layout. NSTextLineFragment contain affordances for rendering, such as -drawAtPoint:inContext:. And UITextInteraction/UITextSelectionDisplayInteraction offer the ability to match system selection UI and gesture behavior.