2012-04-30 20 views
14

CALayer alt sınıfını, dizine dayalı olarak farklı bir resmi görüntülemek için doğrudan canlandırabileceğiniz ve değiştirebileceğim özel bir index özelliği ile oluşturmaya çalışıyorum. başlığında CALayer alt sınıfı nasıl tam olarak özel bir özellik kullanıyorsunuz?

, ben ilan: uygulamada

@property NSUInteger index; 

, ben needDisplayForKey overrode: display yöntemde, ben endeksine dayalı bir resmi görüntülemek istediğiniz, Şimdi

+ (BOOL)needsDisplayForKey:(NSString *)key 
{ 
    if ([key isEqualToString:@"index"]) 
     return YES; 
    else 
     return [super needsDisplayForKey:key]; 
} 

. Ancak, bir animasyon sırasında, self.index değeri hiç değişmez, bu yüzden Providing CALayer Content by Subclassing örneğin aksine sunum katmanı değerini, sorgulamak zorunda:

- (void)display 
{ 
    NSUInteger presentationIndex = [(CustomLayer *)[self presentationLayer] index]; 
    self.contents = (id)[[images objectAtIndex:presentationIndex] CGImage]; 
} 

sorun, bunu yaparsam, yapamam olduğunu index değerini doğrudan bir animasyonun dışına ayarlayın, çünkü yalnızca model katmanını değiştirir ve display yöntemi, sunum katmanını açık bir şekilde sorgular. Ben index değeri, çalışıyor kopyalar bir başlatma yöntemi eklerseniz

:

- (id)initWithLayer:(id)layer 
{ 
    self = [super initWithLayer:layer]; 
    if (self) { 
     if ([layer isKindOfClass:[CustomLayer class]]) 
      self.index = [(CustomLayer *)layer index]; 
    } 
    return self; 
} 

Ancak sonra veya bir animasyonun önce, her zaman çünkü 1 resim aksaklık olduğunu sunum veya model değeri don Eşleşmiyor (hedef değere index ayarlamamıza bağlı olarak).

  • Şaşırtıcı drawInContext: yöntem her zaman [self index] için doğru değere sahip gibi görünüyor, ama ben sadece bir resim ile content özelliğini ayarlayın beri kullanmak istediğiniz yöntemi değildir.
  • index özelliğini uygulamam şekline bağlı olarak farklı davranışlar alıyorum. @dynamic index kullanırsanız (bu, belgeler, özel özellikli alıcı/ayarlayıcıların dinamik olarak uygulanacağını söylemez), index değeri her değiştiğinde display çağrılır. @synthesize kullanıyor veya bir set uygulamıyorsam, display çağrılmıyorsa, content ayarlayıcısında da değiştirmem gerekiyor.
  • Örnek değişken kullanmalı mıyım? Dinamik uygulamayı kullanmalı mıyım? Yoksa bunun yerine setValue:forKey: kullanmalı mıyım?

Gördüğünüz gibi, istediğim sonucu nasıl alacağımı ve CALayer alt sınıfını özel bir özellikle doğru şekilde nasıl uygulayacağımı biraz kafam karıştı. Herhangi bir yardım ve açıklama, takdir edilecektir!

+2

"dokümantasyon o özel özellik getters/ayarlayıcılar dinamik uygulanacağına dair demiyor" - aslında, bu * olduğunu * belgelenen CALayer.h: "CALayer, sınıf ve alt sınıfları tarafından tanımlanan tüm Objective C özellikleri için standart NSKeyValueCoding protokolünü uygular. Alt sınıflar tarafından bildirilen özellikler için eksik erişim yöntemlerini dinamik olarak uygular." Yani çalışmak istiyorsanız, '+ needsDisplayForKey:' istiyorsanız '@ dynamic' kullanmak istersiniz. –

+2

Harika bir soru… Bu "temel" sorular, dokümanlar altında açıklanmıyor ve nasıl yapıldığının tamamen dahil olduğu için çok ezoterik. 'CALayer' garip-toplar .. Bence Apple onların uygulanmasından pişmanlık duyuyor ya da çok gizemli davranışlarını belgelemekten rahatsız olacak çok fazla rakip teknolojiye sahip. –

+3

Katılıyorum ... Temel Animasyon temel görevler için kullanışlıdır, ancak daha derine inmeye çalışırsanız, ezoterik hale gelir. Animasyon zamanlamasına ek olarak katmanların zamanlaması olduğu gibi. Veya türü "id" olan ve önbelleğe alınmış bir "CABackingStore" içeren gizemli 'content' özelliği. Ya da “CATransition” ın “CAAnimation” dan miras alması gerçeği tamamen opak bir şekilde çalışır ... Hatta UIView animasyon blokları ve “CALayer” animasyonu arasındaki ilişki ... – Guillaume

cevap

11

Web üzerinde, animatable özelliklerine sahip özel bir CALayer alt sınıfının nasıl oluşturulacağını açıklayan mükemmel bir eğitici var. Henüz denemek için bir fırsatım olmadı, ama onu işaretledim.

Animating Pie Slices Using a Custom CALayer

ana hileler şunlardır benziyor:

kullanın @dynamic, aramaları özel CALayer ait canlandırılabilir özellikleri için @synthesize değil İşte bağlantıdır.

geçersiz kıl actionForKey :, initWithLayer :, ve needsDisplayForKey :, ve belki drawInContext:

+0

Bu örnek kendi CoreGraphics çizim rutinini kullanır. 'drawInContext:', dediğim gibi, her zaman animasyonlu özellik için doğru değere sahip. Ancak 'display' yönteminde, yalnızca sunulan değer doğrudur. Sonunda istediğim sonucu elde etmek için kullandığım geçici çözüm, özelliği bir animasyonun dışında değiştirmek istediğimde özelliği sentezlemek ve "setNeedsDisplay" öğesini manuel olarak çağırmaktır. – Guillaume

+0

Komik .. Bunu görmüştüm, ve aslında her şeyi bir Mac için, hatta çalışıyor. Çalışan sınıfları denemeye çalışacağım. –

İlgili konular