рисовать в отдельных слоях-цель c основной графикой

Я разрабатываю приложение для построения графиков для iphone, используя базовую графику. Мое требование заключается в следующем. Я реализовал все свои функции рисования внутри метода drawRect. когда в диаграмме происходит какое-то обновление, мне нужно вызвать [self setNeedsDisplay: true], и ​​он вызывает метод drawRect с самого начала. (означает, что он выполняет все методы внутри drawRectMethod. поэтому рисование при касании происходит не очень гладко. мне нужно нарисовать некоторые определенные части в методе drawRect вместо всех. Возможно ли это с основной графикой?


person Charith Nidarsha    schedule 30.12.2009    source источник


Ответы (1)


Непонятно, что вы имеете в виду под «отдельными слоями», но из вашего вопроса я предполагаю, что вы имеете в виду, что -drawRect: в настоящее время является большой сложной функцией, которая выполняет много вычислений и поэтому выполняется слишком медленно, потому что ее часто вызывают. Вы не упоминаете CALayer, поэтому я предполагаю, что вы не имеете в виду настоящие слои здесь.

Решение этой проблемы - переместить свои вычисления из -drawRect:. Вы должны рассчитывать все, что вам нужно, только тогда, когда данные действительно изменятся. Затем в -drawRect: вы должны использовать предварительно рассчитанные значения, что должно быть намного быстрее.

Например, поскольку вы упоминаете Core Graphics, я предполагаю, что вы используете такие вещи, как CGPath. Вы должны рассчитывать свой CGPath только при изменении данных, а затем сохранять CGPath в ivar. Вам нужно просто нарисовать свой CGPath в -drawRect:. Если CGPath является особенно сложным (и, следовательно, медленным), вы можете даже предварительно отрендерить его в CGImage, а затем просто составить CGImage.

По возможности на iPhone следует полностью избегать Core Graphics, а вместо этого предварительно отрендерить изображения в Photoshop и сохранить их в папке «Ресурсы». 3G просто не требуется вычислительной мощности, чтобы не отставать от сложной обработки Core Graphics. Это отмена недавних рекомендаций Apple для Mac, которые не рекомендуют использовать предварительно обработанные изображения и поощряют градиенты и траектории, а с 3GS это менее критично из-за гораздо более быстрого процессора, но все же это текущая рекомендация для iPhone. и, вероятно, будет до тех пор, пока они не выпустят дисплей iPhone с более высоким разрешением. Это, конечно, невозможно, если у вас есть динамическое изображение, но вы должны помнить об этом для статических изображений.

РЕДАКТИРОВАТЬ:

Во-первых, если это возможно, убедитесь, что вы рисуете только те части, которые грязные. -drawRect: передает вам грязный прямоугольник. Если конкретный элемент не пересекает этот прямоугольник, вам не нужно его перерисовывать. Точно так же вы должны использовать -setNeedsDisplayInRect:, чтобы указать, какие элементы нуждаются в обновлении. Если вы можете легко разбить вид на неперекрывающиеся прямоугольники (или иногда перекрывающиеся прямоугольники), тогда это хорошо работает.

Если у вас есть представление, состоящее из различных перекрывающихся компонентов, которые вы хотели бы вычислить независимо, тогда вы можете нарисовать каждый на CALayer, а затем прикрепить слои к виду (возможно, ничего не рисуя на самом виде). Затем вы можете вызвать -setNeedsDisplay только для измененных слоев. Это то, что я, вероятно, использовал бы для примера вертикальной линии. Я бы создал CALayer ширину линии и высоту представления, установил цвет фона на цвет линии и прикрепил его к представлению в желаемой позиции. Затем линия перемещается очень быстро (или даже вращается с помощью преобразования), и удалить линию позже - тривиально. Если вам нужно более красивое рисование линий (сглаживание и т.п.), вы, конечно, можете сделать слой шире и на самом деле нарисовать линию внутри слоя. При необходимости слой может быть такого же размера, как и вид.

Базовое руководство по программированию анимации содержит обширную документацию по CALayer и как это использовать.

person Rob Napier    schedule 30.12.2009