Próbuję utworzyć podklasę o wartości CALayer
z niestandardową właściwością index
, którą mogę zarówno animować, jak i zmieniać bezpośrednio, aby wyświetlić inny obraz na podstawie indeksu.Jak dokładnie podklasę CALayer i użyć niestandardowej właściwości?
W nagłówku, oświadczyłem:
@property NSUInteger index;
W realizacji, ja overrode needDisplayForKey
:
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"index"])
return YES;
else
return [super needsDisplayForKey:key];
}
Teraz w sposobie display
, chcę, aby wyświetlić obraz na podstawie indeksu . Jednak w trakcie animacji, wartość self.index
nigdy się nie zmienia, więc muszę zapytać wartość warstwy prezentacji, w przeciwieństwie do przykładu na Providing CALayer Content by Subclassing:
- (void)display
{
NSUInteger presentationIndex = [(CustomLayer *)[self presentationLayer] index];
self.contents = (id)[[images objectAtIndex:presentationIndex] CGImage];
}
Problem polega na tym, czy to zrobić, nie mogę Ustaw wartość index
bezpośrednio poza animacją, ponieważ zmieni ona tylko warstwę modelu, a metoda display
jawnie zapyta o warstwę prezentacji.
Jeśli dodać metodę inicjalizacji, która kopiuje wartość index
, to działa:
- (id)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self) {
if ([layer isKindOfClass:[CustomLayer class]])
self.index = [(CustomLayer *)layer index];
}
return self;
}
Jednak po lub przed animacji, zawsze jest glitch 1 obraz, ponieważ prezentacja lub wartość modelu don dopasowanie (w zależności, czy ustawię index
na wartość docelową, czy nie).
- Co ciekawe, wydaje się, że metoda
drawInContext:
zawsze właściwą wartość dla[self index]
, ale to nie jest metoda chcę używać, ponieważ po prostu ustawić właściwość z obrazemcontent
. - Dostaję różne zachowania w zależności od sposobu, w jaki implementuję właściwość
index
. Jeśli użyję@dynamic index
(która działa, nawet jeśli w dokumentacji nie jest powiedziane, że niestandardowe właściwości pobierające/ustawiające będą dynamicznie zaimplementowane),display
jest wywoływane za każdym razem, gdy zmieniana jest wartośćindex
. Jeśli użyję@synthesize
lub zaimplementuję ustawiacz,display
nie zostanie wywołany, więc będę musiał zmienić takżecontent
w ustawiaczu. - Czy powinienem użyć zmiennej instancji? Czy powinienem użyć dynamicznej implementacji? Czy powinienem zamiast tego użyć
setValue:forKey:
?
Jak widać, jestem trochę zdezorientowany o tym, jak uzyskać wynik chcę i jak prawidłowo realizować podklasy CALayer z właściwości niestandardowej. Każda pomoc i objaśnienia zostaną docenione!
„Dokumentacja nie mówi, że zwyczaj pozyskiwaniu nieruchomości/ustawiaczy będzie dynamicznie realizowane” - faktycznie, to * jest * udokumentowane 'CALayer.h':" CALayer implementuje standardowy protokół NSKeyValueCoding dla wszystkich właściwości Celu C zdefiniowanych przez klasę i jej podklasy, dynamicznie implementuje brakujące metody akcesorów dla właściwości zadeklarowanych przez podklasy. " Więc chcesz użyć '@ dynamic', jeśli chcesz, aby' + needsDisplayForKey: 'działało. –
Świetne pytanie ... Te "podstawowe" pytania są niedostatecznie wyjaśnione w dokumentach i zbyt ezoteryczne dla wszystkich, ale najbardziej zaangażowanych w poradniki. "CALayer's to takie dziwne kule. Myślę, że Apple żałuje ich wdrożenia lub ma zbyt wiele konkurencyjnych technologii, aby zawracać sobie głowę dokumentowaniem swoich często tajemniczych zachowań. –
Zgadzam się ... Podstawowa animacja jest trywialna w użyciu w podstawowych zadaniach, ale jeśli spróbujesz sięgnąć głębiej, stanie się ezoteryczna. Podobnie jak fakt, że warstwy mają taktowanie, oprócz czasu animacji. Lub tajemnicza właściwość 'contents', której typem jest' id', i która może zawierać buforowany 'CABackingStore'. Albo fakt, że "CATransition" dziedziczy po 'CAAnimation' działa w całkowicie nieprzejrzysty sposób ... Albo nawet relacja między blokami animacji" UIView "i animacją" CALayer "... – Guillaume