Как создать CGLayer из UIView для рисования вне экрана - PullRequest
5 голосов
/ 11 февраля 2011

Я прочитал, как мне кажется, соответствующие части Руководства по программированию в Quartz 2D, но не могу найти ответ на следующий вопрос (кажется, они мало говорят об iOS в документе):

Мое приложение отображает рисунок в UIView. Время от времени я должен каким-то образом обновлять чертеж, например, измените цвет заливки одной из фигур (я оставляю CGPathRefs на важных фигурах, чтобы позже можно было перерисовать их другим цветом заливки). Как описано в разделе «Рисование с помощью CGLayer» на странице 169 вышеупомянутого документа, я думал о том, чтобы нарисовать весь чертеж в CGContext, который я получил бы из CGLayer, например:

CGContextRef offscreenContext = CGLayerGetContext(offscreenLayer);

Затем я мог бы выполнить свое обновление за пределами экрана в CGContext и нарисовать CGLayer в моем UIView в методе drawRect: UIView, например:

CGContextDrawLayerAtPoint(viewContext, CGPointZero, offscreenLayer);

У меня проблема в том, откуда мне взять CGLayer? Насколько я понимаю, я должен сделать это, используя CGLayerCreateWithContext и предоставить CGContext в качестве параметра, от которого он наследует большинство своих свойств. Очевидно, что правильным контекстом будет контекст UIView, который я получаю с

CGContextRef viewContext = UIGraphicsGetCurrentContext();

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

Итак, как я могу получить CGContext, который я могу использовать для инициализации моего CGLayer, чтобы создать внеэкранный CGContext для рисования, а затем нарисовать весь слой обратно в UIView моего *1030*

PS: пока вы на нем; если что-то выше не имеет смысла или не является нормальным, пожалуйста, дайте мне знать. Я только начинаю думать о Quartz 2D.

1 Ответ

1 голос
/ 23 марта 2011

Прежде всего, если вы делаете это из среды iOS, я думаю, что вы правы.В документации четко сказано, что единственный способ получить CGContextRef - это

CGContextRef ctx = UIGraphicGetCurrentContext();

. Затем вы используете этот контекст для создания CGLayer с

CGLayerRef layer = CGLayerCreateWithContext(ctx, (CGSize){0,0}, NULL);

И если вы хотитечтобы нарисовать на этом слое, вы должны нарисовать его с контекстом, который вы получаете от слоя.(Это несколько отличается от контекста, который вы передали ранее для создания CGLayer).Я предполагаю, что CGLayerCreateWithContext сохраняет информацию, которую он может получить из переданного контекста, но не все.(Одним из примеров является информация о ColorSpace, которую необходимо переопределить при заполнении чего-либо контекстом из CGLayer).

Вы можете получить ссылку на контекст CGLayer из функции CGLayerGetContext() и использоватьчто рисовать.

CGContextRef layerCtx = CGLayerGetContext(layer);
CGContextBeginPath(layerCtx);
CGContextMoveToPoint(layerCtx, -10, 10);
CGContextAddLineToPoint(layerCtx, 100, 10);
CGContextAddLineToPoint(layerCtx, 100, 100);
CGContextClosePath(layerCtx);

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

И последнее: если вы сохраните ссылку на слой в переменную, а затем захотите нарисовать ее, вы можете использовать метод CGContextDrawLayerAtPoint(), например * 1020.*

CGContextDrawLayerAtPoint(ctx, (CGPoint) {newPointX, newPointY}, layer);

Это будет своего рода «пометить» или «нарисовать» слой с этой новой точкой PointX и новой координатой PointY.

Я надеюсь, что ответьте на ваш вопрос, если нет, дайте мне знать.1025 *

...