I have an NSLayoutManager
which is drawing text using the following code:
[[self textLayoutManager] drawGlyphsForGlyphRange: NSMakeRange(0, [[self text] length])
atPoint: textFrame.origin];
in my view's -drawRect:
. This works wonderfully, but what I'd really like to be able to do is animate the text in, character by character, as if it were being typed.
I've tried to append characters to a "visible string" variable, then call -[self setNeedsDisplay]
, but when dealing with text over approximately 20 characters, it begins to lag, as it redraws all of the text every time.
Regression: How can I animate NSLayoutManager
's -drawGlyphsForGlyphRange:atPoint:
?
(Disclaimer: I don't have a terrible lot of experience with the new APIs, so this is mostly coming from previous experience with text rendering.)
Your major slowdown is going to come from full-on changing the text the layout manager is working with. Even if you're just appending text, replacing the text it's using is going to cause it to throw out all its layout calculations - spacing, needed glyphs, actually reading those glyphs into RAM, applying attributes, etc. - and start over, which gets very expensive very quickly. In terms of actual
NSLayoutManager
, this is "invalidating the layout".I see a couple of potential solutions off the top of my head. You could subclass
NSLayoutManager
("You can create a subclass of NSLayoutManager to handle additional text attributes, whether inherent or not.") and override theshowCGGlyphs:positions:count:font:matrix:attributes:inContext:
to progressively ignore certain glyphs (thereby leaving the original text it's using intact). Another approach would be to emulate exactly what happens when you input text in a native container - use a mutable text storage, and append the desired text character-by-character, so that text calculation is done iteratively.If those alone still don't have great performance, consider using those techniques in tandem with some of the native text views; although this is less true now than in past SDKs, a non-editable
UITextView
or aUILabel
(for mutable and immutable text, respectively) contain far more optimizations than our mere mortal minds could comprehend.