2009-08-31 3 views
1

Простая живопись:
Дыхание экрана iPhone рисует временную графику UIView. Эти временные графики стираются после завершения нажатия и затем сохраняются в базовом UIView.Улучшение характеристик окраски пальцев

Процесс прост:
1) Нажмите Запускает & Moves >>
2) Paint Временные графики на верхней UIView >>
3) сенсорный Окончание >>
4) Pass Temporary Graphics В базовый UIView >>
5) В основе UIView добавлена ​​временная графика для сохраненной графики >>
6) Основополагающие UIView Re-Рисует все Хранимые Графика >>
7) удалить временные графики на верхней UIView.

Таким образом, я могу накапливать графику на базовом UIView, сохраняя при этом отзывчивую окраску временной графики на верхнем UIView.

(Sidenote: Каждый «Рисунок» является просто NSArray обычая «Точечные» Объекты, которые только NSObject контейнеры для CGPoints и подстилающей UIView имеет отдельную NSArray, где он хранит эти NSArrays из CGPoints.)

Проблема заключается в следующем:
Когда на базовом UIView накопилось много графики, требуется время, чтобы нарисовать все на экране. И любые новые рисунки в верхнем UIView не будут отображаться до тех пор, пока чертеж базовой хранимой графики не будет завершен. Таким образом, наблюдается заметное отставание, когда многие графики находятся на экране.

Вопрос:
Может кто-нибудь придумать хороший способ повышения производительности здесь, так что не существует заметная задержка между рисунками, когда есть много графики на экране?

ответ

2

NSArray CGPoints? Вы имеете в виду NSArray из NSValues, где хранятся CGPoints? Это невероятно дорогостоящий способ сохранить то, что должно быть огромным количеством ценностей, к которым вы постоянно обращаетесь. Вы можете хранить эту информацию многими способами. Наиболее очевидна 2-мерная C-матрица, представляющая весь экран. Вы также можете посмотреть в изображения растровых изображений и напрямую в CGImage, а не поддерживать кучу CGPoints. Взгляните на Quartz 2D Programming Guide.

EDIT:

Ваш объект (ниже) является эквивалентом NSValue, только немного более специализированы. Здесь много накладных расходов, когда у вас много, много объектов (~ 100 000, я предполагаю, когда экран почти заполнен, больше, если вы не удаляете дубликаты, запустите Инструменты для его профилирования). Старые структуры данных C, вероятно, будут намного быстрее для этого, потому что вы можете избежать всех сохранений/выпусков, распределений и т. Д. Однако есть и другие варианты. Повторная проверка точек будет намного быстрее с NSMutableSet, если вы выровняете по пикселям CGPoints и перегрузите -isEqual на объект Point.

Убедитесь, что вы выравниваете по пикселям свои данные. Опираясь на дробные пиксели (и сохраняя их все), можно значительно увеличить количество задействованных объектов и количество рисования, которое вы делаете. Даже если вы хотите сглаживание, по крайней мере, вокруг пикселей до .5 (или .25 или что-то). CGPoint состоит из двух двухместных. Вам не нужна такая точность, чтобы рисовать на экране.

+0

Нет, я не использовал NSValue для хранения CGPoints. Я подклассифицировал NSObject и дал ему два члена: xCoord и yCoord, которые являются CGPoints. Фактически производительность не кажется такой плохой, пока экран почти не покрыт графикой. Я не получаю доступ к сохраненной графике до тех пор, пока пользователь не поднимет свой палец (только между рисунками), и в это время я рисую все, что хранится ... Я поддерживаю точки, чтобы я мог отступать и выполнять отмена, когда необходимо. Будет ли C-массив быстрее? – RexOnRoids

+0

Отредактированный ответ на основе комментария. –

1

Почему бы просто не нарисовать все на буфере CGBitmapContextRef, чтобы операции рисования накопились, а затем нарисуйте это на экране в вашем drawRect:? Вы сможете выполнять произвольные графические операции без замедления по мере увеличения общего количества операций.

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

+0

спасибо за этот ответ. Как сделать несколько CGImageRefs (каждый из которых представляет собой шаг пера) вместе в методе -drawRect:? – RexOnRoids

+0

Вы должны использовать один CGBitmapContextRef в качестве резервного буфера. Когда вы рисуете новый путь в контексте, он рисует поверх старого содержимого. В drawRect представления: используйте CGBitmapContextCreateImage, чтобы получить изображение, а затем нарисуйте это на своем представлении. Для реализации этого требуется только один CGBitmapContextRef – rpetrich

Смежные вопросы