Ваша догадка верна, на самом деле это отличный способ оптимизировать рисование. Я сделал это сам, когда у меня были большие статические фоны, которые я хотел избежать перерисовки, когда элементы перемещались сверху.
Все, что вам нужно сделать, это добавить CALayer
объектов для каждого элемента контента в вашем представлении. Чтобы рисовать слои, вы должны установить свое представление в качестве делегата для каждого слоя, а затем реализовать метод drawLayer:inContext:
.
В этом методе вы просто рисуете содержимое каждого слоя:
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
if(layer == yourBackgroundLayer)
{
//draw your background content in the context
//you can either use Quartz drawing directly in the CGContextRef,
//or if you want to use the Cocoa drawing objects you can do this:
NSGraphicsContext* drawingContext = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
NSGraphicsContext* previousContext = [NSGraphicsContext currentContext];
[NSGraphicsContext setCurrentContext:drawingContext];
[NSGraphicsContext saveGraphicsState];
//draw some stuff with NSBezierPath etc
[NSGraphicsContext restoreGraphicsState];
[NSGraphicsContext setCurrentContext:previousContext];
}
else if (layer == someOtherLayer)
{
//draw other layer
}
//etc etc
}
Если вы хотите обновить содержимое одного из слоев, просто вызовите [yourLayer setNeedsDisplay]
. Затем это вызовет метод делегата выше, чтобы предоставить обновленное содержимое слоя.
Обратите внимание, что по умолчанию, когда вы меняете содержимое слоя, Core Animation обеспечивает хороший плавный переход для нового содержимого. Однако, если вы обрабатываете рисунок самостоятельно, вам, вероятно, это не нужно, поэтому, чтобы предотвратить анимацию постепенного исчезновения по умолчанию при изменении содержимого слоя, вам также необходимо реализовать метод делегата actionForLayer:forKey:
и предотвратить анимацию, возвращая нулевое действие:
- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)key
{
if(layer == someLayer)
{
//we don't want to animate new content in and out
if([key isEqualToString:@"contents"])
{
return (id<CAAction>)[NSNull null];
}
}
//the default action for everything else
return nil;
}
person
Rob Keniger
schedule
21.02.2012