Создание пользовательского представления для рисования текста - PullRequest
3 голосов
/ 10 мая 2009

Я создаю подсветку синтаксиса для iPhone, и для отображения текста в нескольких форматах я создал подкласс UIView и изменил метод drawRect:, чтобы каждая строка отображалась с правильной подсветкой синтаксиса (выделение выполнено ранее с RegEx текст рисуется с CGContextShowTextAtPoint() по одной строке за раз). Все работает нормально, я сохраняю каждую строку текста как NSString в NSMutableArray, я управляю клавиатурой через скрытый UITextField и его методы делегата, курсор представляет собой мигающий CALayer, который можно перемещать касаниями, и у меня есть собственное представление прокрутки это обрабатывает прокрутку. Однако у меня есть две проблемы, которые я, кажется, не могу обернуть вокруг:

  1. Перенос слов, сейчас текст просто продолжает уходить с левого края экрана. Чтобы ускорить процесс, я перерисовываю только те части представления, которые изменились (обычно это только редактируемая строка, но иногда и строки ниже, например, если вы нажмете кнопку возврата на полпути через документ) с помощью setNeedsDisplayInRect:. Это усложняет перенос слов, потому что тогда вам нужно нарисовать более одной линии на экране, хотя это все еще только один объект в массиве.

  2. Максимальный размер содержимого UIViews составляет 1024x1024, что соответствует примерно 64 строкам. Мне нужна способность отображать больше, чем это. Я думаю об использовании нескольких слоев CAL один за другим, но у меня возникают проблемы с отображением содержимого в слои (используя drawLayer:inContext: и drawInContext:).

Итак, мои вопросы:

  • Есть ли у кого-нибудь, даже общие, предложения о том, как выполнить любой из этих двух пунктов. Или,
  • Кто-то уже написал собственный вид для рисования текста, который обрабатывает эти вещи, которые я мог бы использовать вместо этого.

Спасибо

Кайл

РЕДАКТИРОВАТЬ: Проблема прокрутки в значительной степени решена, однако у меня все еще есть проблемы с переносом слов. Моя проблема в том, что все делается построчно: представление обновляется по одной строке за раз, текст сохраняется в виде массива строк, маркер выделяет одну строку за раз и т. Д. И имеет один индекс в массиве (один текстовая строка), занимающая несколько строк на экране, порождает некоторые проблемы, например, мне пришлось реализовать собственный подвижный курсор, и когда вы перемещаете курсор, он должен иметь возможность поворачивать строку дисплея (что определяется делением touch.x на высота строки) в текстовую строку (индекс в массиве). Есть идеи?

Ответы [ 3 ]

1 голос
/ 11 мая 2009

Сначала вы должны потратить некоторое время на понимание того, как эта проблема была решена на Mac:

http://developer.apple.com/documentation/Cocoa/Conceptual/TextArchitecture/Tasks/AssembleSysByHand.html

http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/TextLayout.html

В частности, вы должны познакомиться с генерацией фрагмента строки, который является проблемой, которую вы пытаетесь решить для переноса слов, и вы должны понимать генерацию глифа, чтобы хорошо выполнять форматированный текст. Вам, конечно, не нужно реализовывать всю гибкость NSTypesetter или NSLayoutManager, но текстовая система на Mac невероятно мощная, и вы должны учиться на ее примере. Реализация чего-то похожего на NSAttributedString для iPhone может оказаться полезной для вас и повысить вашу производительность.

Если вы много не перемещаете вещи (для которых это лучше всего работает в UIScrollView), я не думаю, что вам здесь нужно использовать CALayers. Это кажется излишним для проблемы, и может фактически отрицательно повлиять на оптимизацию, уже обеспеченную UIScrollView. Если вы видите проблемы с производительностью, сначала убедитесь, что вы не выполняете избыточные вычисления в вашем drawRect:.

1 голос
/ 11 мая 2009

Проверьте TTStyledText в библиотеке Three20 . Не уверен, насколько это соответствует вашим целям, но может служить вам примером. (Сама библиотека немного раздута, но это прекрасный источник для изучения.)

0 голосов
/ 10 мая 2009

Может быть лучше нарисовать ваш текст в CATiledLayer, размещенном в вашем UIView, чтобы обойти ограничение размера текстуры 1024x1024 (которое на самом деле составляет 2048x2048 на всех существующих устройствах). Для примера рисования текста в CALayer я бы сослался на класс CPTextLayer в рамках Core Plot . Этот слой (который наследуется от класса CPLayer в той же платформе) выполняет кроссплатформенный (Mac и iPhone) рендеринг текста в CALayer. Возможно, вы сможете расширить его для работы в качестве CATiledLayer для более длинных текстовых блоков.

Следует помнить одну вещь: в этом слое используются методы drawAtPoint: специфичные для платформы, а не используемая вами функция CGContextShowTextAtPoint (). Причиной этого является то, что CGContextShowTextAtPoint () работает только с текстом ASCII, что означает, что вы не можете выполнять рендеринг текста Unicode с ним. Есть пример использования CGContextShowTextAtPoint () для рисования текста внутри части # define'd out в нижней части renderAsVectorInContext: метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...