Проблема производительности CALayer: анимация линии, привязанной между двумя UIViews - PullRequest
0 голосов
/ 29 декабря 2010

У меня есть приложение для iPad, в котором есть перетаскиваемые UIViews, содержащиеся в более крупном родительском UIView (который я назову основным видом). Одной из особенностей приложения является возможность перетаскивания между двумя видами для их соединения. При перетаскивании я отрисовываю линию в CALayer, которая укоренена в представлении, на котором вы начали перетаскивать, и заканчивается на пальце пользователя. Если пользователь заканчивает перетаскивание поверх другого представления, они присоединяются.

Когда виды прикреплены, между ними постоянно рисуется линия.

Таким образом, в текущей реализации есть два слоя CALay, которые являются подуровнями основного представления. Одним из них является linkLayer, который отображает существующие ссылки между представлениями. другой - linkLineLayer, который отображает линию, которую пользователь в данный момент рисует, с действием перетаскивания.

Когда происходит перетаскивание и появляется новое событие перетаскивания, я вызываю [linkLineLayer setNeedsDisplay]. аналогично, когда пользователь перетаскивает вид, я вызываю [linkLayer setNeedsDisplay].

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

Обновление Прошлой ночью я вошел и сделал два исправления, которые имели огромное значение: 1.) все линии связи имеют свой собственный слой. так как представление перетаскивается, я обновляю только линии связи, связанные с этим конкретным представлением.
2.) обновил «линию перетаскивания», чтобы она стала слоем, размер которого ограничен размером отображаемой линии. я настраиваю границы слоя, когда палец пользователя движется.

1 Ответ

4 голосов
/ 04 января 2011

Вы пробовали рендерить строки как CAShapeLayer s?Вместо того, чтобы рисовать линию самостоятельно и постоянно вызывать setNeedsDisplay, вы можете просто установить атрибут path CAShapeLayer и позволить ему делать все остальное.

Core Animation handle CAShapeLayer sпо-другому, и это может оптимизировать рисование пути.Если вы просто нарисуете путь в drawLayer:inContext: (или эквивалентном), Core Animation должна рассматривать весь слой как изображение, потому что она не знает, что вы нарисовали.Если вы используете CAShapeLayer, Core Animation знает путь, который вы хотите нарисовать заранее, и может соответствующим образом оптимизировать его рендеринг.Вам также не нужно беспокоиться о размере и положении слоя формы, потому что слой просто путь.

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

...