Анимация рисунка NSLayoutManager

У меня есть NSLayoutManager, который рисует текст, используя следующий код:

[[self textLayoutManager] drawGlyphsForGlyphRange: NSMakeRange(0, [[self text] length])
                                          atPoint: textFrame.origin];    

на мой взгляд -drawRect:. Это прекрасно работает, но мне бы очень хотелось иметь возможность анимировать текст, символ за символом, как если бы он печатался.

Я пытался добавить символы к переменной «видимой строки», а затем вызвать -[self setNeedsDisplay], но при работе с текстом более 20 символов он начинает отставать, так как каждый раз перерисовывает весь текст.

Регрессия: как мне оживить -drawGlyphsForGlyphRange:atPoint: NSLayoutManager?


person Patrick Perini    schedule 01.12.2013    source источник


Ответы (1)


(Отказ от ответственности: у меня нет большого опыта работы с новыми API, так что это в основном исходит из предыдущего опыта с рендерингом текста.)

Ваше основное замедление будет происходить из-за полного изменения текста, с которым работает менеджер компоновки. Даже если вы просто добавляете текст, замена текста, который он использует, приведет к тому, что он отбросит все свои расчеты макета — интервалы, необходимые глифы, фактическое чтение этих глифов в ОЗУ, применение атрибутов и т. д. — и начнет все сначала, что очень быстро дорожает. С точки зрения фактического NSLayoutManager, это «аннулирование макета».

Я вижу пару потенциальных решений навскидку. Вы можете создать подкласс NSLayoutManager ("Вы можете создать подкласс NSLayoutManager для обработки дополнительных текстовых атрибутов, встроенных или нет") и переопределить showCGGlyphs:positions:count:font:matrix:attributes:inContext:, чтобы постепенно игнорировать определенные глифы (тем самым оставляя исходный текст, который он использует, нетронутым). Другой подход заключается в том, чтобы точно эмулировать то, что происходит, когда вы вводите текст в собственный контейнер, - используйте изменяемое хранилище текста и добавляйте желаемый текст посимвольно, чтобы вычисление текста выполнялось итеративно.

Если только они по-прежнему не обеспечивают высокой производительности, рассмотрите возможность использования этих методов в тандеме с некоторыми собственными текстовыми представлениями; хотя сейчас это менее верно, чем в прошлых SDK, нередактируемые UITextView или UILabel (для изменяемого и неизменяемого текста соответственно) содержат гораздо больше оптимизаций, чем наши простые смертные могут понять.

person zwaldowski    schedule 01.12.2013