2012-02-21 12 views
5

Sık sık değişen bazı içeriklere sahip olan ve çok seyrek olarak değişebilen bazı özel bir NSView nesnesi yapıyorum. Ortaya çıkacağı gibi, daha az değişen parçalar çizmek için en fazla zamanı alır. Yapmak istediğim şey, bu iki parçayı farklı katmanlarda işlemek, böylece birini veya diğerini ayrı ayrı güncelleyebilmem, böylece kullanıcımı yavaş bir kullanıcı arabirimi olarak koruyabiliyorum.Görünüm oluşturmayı hızlandırmak için CALayer kullanabilir miyim?

Bunu yapmayı nasıl yapabilirim? Bu tür şeyler hakkında pek çok iyi öğretici bulamadım ve NSBezierPaths'ı bir CALayer üzerinde işlemek konusundaki hiçbir şey yok. Fikirler kimse?

cevap

4

Önseziniz doğru, bu aslında çizimi optimize etmenin mükemmel bir yoludur. Öğeleri üstüne taşındığında yeniden çizilmekten kaçınmak istediğim bazı büyük statik geçmişlerimin olduğu yerde kendim yaptım.

Yapmanız gereken tek şey, görünümünüzdeki içerik öğelerinin her biri için CALayer nesnesi eklemektir. Katmanları çizmek için, görünümünüzü her katman için temsilci olarak ayarlamalı ve ardından drawLayer:inContext: yöntemini uygulamalısınız. Bir tabakaların içeriğini güncellemek istediğinizde sadece [yourLayer setNeedsDisplay] diyoruz,

- (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 
} 

:

o yöntemde sadece her katmanın içeriğini çizin. Bu, katmanın güncellenmiş içeriğini sağlamak için yukarıdaki temsilci yöntemini çağırır.

Varsayılan olarak, katman içeriğini değiştirdiğinizde, Çekirdek Animasyon yeni içerik için güzel bir geçiş geçişi sağlar. Ancak, çizimi kendiniz ele alıyorsanız, muhtemelen bunu istemezsiniz. Bu nedenle, katman içeriği değiştiğinde animasyonda varsayılan solmayı önlemek için, actionForLayer:forKey: delege yöntemini de uygulamanız gerekir. boş eylem:

+0

Teşekkürler, bu çok yardımcı oluyor. Ancak delege yönteminin ateş edilmesinde sorun yaşıyorum. Görüşümü delege olarak ayarlıyorum ve katmanları kök katmanının alt katmanları olarak ekliyorum ve ben 'setNeedsDisplay' çağrısı yapıyorum ama 'drawLayer: inContext' asla çağrılmıyor. Herhangi bir fikir? – mtmurdock

+0

Kodunuzu gönderir misiniz? Bu çalışmalı. –

+0

Ayrıca "drawRect:" yi de geçersiz kılıyordum, bu başka bir işlevi çağırmamasına neden olabilir mi? – mtmurdock