Постепенно добавляя в UIView - PullRequest
7 голосов
/ 13 июня 2011

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

Я попытался разбить путь на множество различных сегментов, которыепозволяет рисовать только те сегменты, которые находятся в прямоугольнике, переданном мне в drawRect:, и это значительно помогает, но рисование все еще идет медленно;многие сегменты перерисовываются без необходимости, когда к пути в области экрана, которая уже содержит части пути, добавляются разделы.

Я ничего не удаляю из вида, поэтому я попытался включить clearsContextBeforeDrawingи каждый раз при вызове drawRect: рисуйте только последний сегмент, но, похоже, в Интернете есть много неофициальных свидетельств того, что это свойство ничего не делает, и я также не могу заставить его работать вообще.

Каков наилучший способ ускорить рисование?

Из того, что я прочитал, похоже, что мой лучший вариант - рисовать в (закадровом) растровом контексте, так что я могу постепенно добавлять икопирование его в графический контекст, отображаемый на экране, но я также читал, что это часто происходит медленно, как при выделении контекста, так и из-за преобразования RGBA в RGB, которое требуется при рендеринге изображения на экран.

Похоже, что я могу сделать что-то, включающее CALayer (с закадровым буфером или без него)это неясно мне, как рисовать на слое работ и будет ли он обойти бы ни одну из проблем, которые я видел.Свойство contents принимает значение CGImageRef;можно сделать CGImage, а затем обновлять это постепенно, без перерисовки всего?Кроме того, возможно ли добавить к содержанию CALayer, не перерисовывая все это?

Буду признателен за любые идеи.


Редактировать: Длящедрость, пожалуйста, предоставьте пример того, как правильно инициализировать буфер изображения, нарисовать на нем кубический путь Безье и соответствующим образом скопировать его на экран.Также, пожалуйста, запишите, почему использовать ваш метод - я не знаю, лучше ли использовать CGBitmapContextCreate или есть что-то еще, что я должен использовать.

1 Ответ

1 голос
/ 14 июня 2011

BezierPaths хороши тем, что они являются векторами, независимо от разрешения вашего вида они будут хорошо выглядеть.Однако, если вам не нужно изменять размер своего представления, нет необходимости каждый раз вычислять все.Просто вычислите последнюю дугу / линию и нарисуйте ее в предыдущем (закадровом) буфере, это должно улучшить производительность.

Я помню, что делать подобные вещи и производительность не было такой большой проблемой, я получил около 12 кадров в секундув iPhone 3GS.Что не так уж и плохо.(Я не использовал путь Безье точно, я выполнял некоторую обработку изображений с использованием CGImageRefs и необработанных буферов rgba, которые должны быть самой дорогой частью этого подхода. Вычисление только одной дуги / линии BezierPath очень дешево)

...