/ / CALayer: oddzwanianie po zakończeniu animacji? - animacja, animacja rdzenia, calayer, cabasicanimation

CALayer: wywołanie zwrotne po zakończeniu animacji? - animacja, core-animacja, calayer, cabasicanimation

Miałem problemy z animowaniem wielu CALayerów jednocześnie i miałem nadzieję, że ktoś wskaże mi właściwy kierunek.

Moja aplikacja zawiera tablicę CALayer. Pozycja każdej warstwy jest ustawiona na (previousLayer.position.y + previousLayer.bounds.height), który w zasadzie określa je podobnie dostół. Następnie mam metodę, która za każdym razem, gdy jest wywoływana, dodaje nową warstwę do stosu i ustawia jej pozycję Y na 0. Ustawienie Y wszystkich pozostałych warstw w tablicy jest następnie kompensowane przez wysokość nowej warstwa (zasadniczo wypychając wszystkie stare warstwy w dół).

Mam problemy z zapobieganiemdodawanie nowych warstw do czasu zakończenia poprzedniej animacji. Czy istnieje sposób na określenie, kiedy zakończyła się ukryta animacja? Lub alternatywnie, jeśli używam CABasicAnimation i animationDidFinish, czy istnieje sposób, aby powiedzieć, który obiekt zakończył animację, kiedy animationDidFinish jest nazywany?

Odpowiedzi:

4 dla odpowiedzi № 1

Możesz ustawić dowolne wartości kluczy na swoim urządzeniuobiekt animacji. Oznacza to, że możesz powiązać warstwę, którą animujesz, z animacją, a następnie zapytać ją o -animationDidStop: gotowy: Tworzysz animację w ten sposób:

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
// set other fields...

[anim setValue:layerToAnimate forKey:@"layer"];

// Start the animation
[layerToAnimate addAnimation:anim forKey:nil];

Następnie sprawdź tę wartość, gdy animacja się zatrzyma:

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
CALayer *animatedLayer = [animation valueForKey:@"layer"];
// do something with the layer based on some condition...
// spin off the next animation...

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
[animatedLayer setPosition:position];
[CATransaction commit];
}

To wyraźna animacja, ale powinna dać ci to, czego potrzebujesz.


1 dla odpowiedzi nr 2

Możesz spróbować otoczyć swój kod w CATransaction. Oto jak to wyglądałoby w Swift 3:

CATransaction.begin()
CATransaction.setCompletionBlock({
// run after the animations
})
// animtations
CATransaction.commit()

0 dla odpowiedzi № 3

Okazuje się, że zamiast dodawaćCABasicAnimation bezpośrednio do CALayera, musiałem dodać go do słownika „akcji” warstwy ... To pozostawia warstwę w jej końcowej pozycji po zakończeniu animacji, ale nadal wywołuje metodę „animationDidFinish”.

-(void)startAnimation {
if(!animating){
animating = YES;
for(int i=0; i<[tweets count]; i++) {
//get the layer
CETweetLayer *currentLayer = [tweets objectAtIndex:i];

//setup the orgin and target y coordinates
float targetY = currentLayer.position.y + offset;

//setup the animation
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.delegate = self;
currentLayer.actions = [NSDictionary dictionaryWithObject:anim forKey:@"position"];
currentLayer.position = CGPointMake(self.bounds.size.width/2, targetY);
}
}
}

I wtedy...

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
animating = NO;
}