На iOS, почему рисунок UIBezierPath не требует контекста?
В iOS мы можем нарисовать строку в drawRect
с помощью
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 100, 100);
CGContextStrokePath(context);
но мы также можем нарисовать прямоугольник, если мы удалим вышеуказанный код и просто используем:
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];
[path stroke];
Два связанных вопроса:
1) Почему не нужно UIBezierPath
получать или использовать текущий контекст?
2) Что делать, если у меня есть два контекста: один для экрана, а один - растровый контекст, а затем как определить, какой контекст рисовать для UIBezierPath
? Я думал, что это может быть UIGraphicsSetCurrentContext
, но этого не существует.
Ответы
Ответ 1
UIBezierPath
использует контекст. Он использует текущий графический контекст UIKit. Это то же самое, что вы уже получаете с UIGraphicsGetCurrentContext()
.
Если вы хотите, чтобы UIBezierPath
использовал другой контекст, вы можете использовать UIGraphicsPushContext()
, но вы должны помнить, что используете UIGraphicsPopContext()
, когда вы закончите.
Ответ 2
Я подумал, что было бы полезно упомянуть, что CGContextFillRect ~ 8.5x быстрее, чем использование UIBezierPath из того, что я могу сказать (в случае, если производительность является фактором и предполагает, что вам не нужно использовать UIBezierPath для более сложного рисования).
Я добавил несколько примеров для примера Apple HazardMap (http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html), а время в мс на прямой составляет ~ 0,00064 мс/прямой для подхода CGContextFillRect против ~ 0,00543 мс/прямоугольник для подхода UIBezierPath, предположительно b/c, для последнего требуется больше служебных служебных сообщений.
то есть. Я сравниваю использование
CGContextFillRect(ctx, boundaryCGRect);
по сравнению с использованием
UIBezierPath* path = [UIBezierPath bezierPathWithRect:boundaryCGRect];
[path fill];
во внутреннем цикле в HazardMapView (плюс вышеупомянутые изменения для push/pop контекста, который передается в HazardMapView drawMapRect: zoomScale: inContext:).
ЕТА
Ответ 3
В iOS мы можем нарисовать строку в drawRect
, используя
Я выделил важную часть этого утверждения. Внутри drawRect:
контекст уже настроен для вас с помощью UIKit, и любые ориентированные на объект чертежные инструкции идут непосредственно в этот контекст. UIBezierPath
действительно использует этот контекст, его просто не нужно передавать явно.
В Cocoa Коснитесь, всегда должен быть контекст чертежа (в этом случае контекст будет в конечном итоге нарисован на экране). Если вы не были внутри drawRect:
, вам нужно создать контекст самостоятельно.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);
Обратите внимание, что первый вызов функции Получить CurrentContext()
. Когда вы используете интерфейс функционального рисования CoreGraphics, вам нужно передать контекст в каждую функцию, но вы не создаете его здесь, вы просто извлекаете тот, который уже существует.
Графические контексты находятся в стеке. Если вы хотите врисовать контекст, который вы создали, вы нажимаете его на стек с помощью UIGraphicsPushContext()
(как уже упоминал Кевин), затем возвращайтесь к предыдущему.