CALayer: обратный вызов, когда анимация заканчивается?
Я столкнулся с некоторыми проблемами, связанными с анимацией нескольких слоев CALA в одно и то же время, и надеялся, что кто-нибудь сможет указать мне правильное направление.
Мое приложение содержит массив CALayer. Положение каждого слоя установлено в (previousLayer.position.y + previousLayer.bounds.height)
, который в основном выкладывает их аналогично таблице. Затем у меня есть метод, который при каждом вызове добавляет новый слой в стек и устанавливает его позицию Y равной 0. Затем позиции Y всех других слоев в массиве смещаются на высоту нового слой (по сути, толкая все старые слои вниз).
У меня проблемы с предотвращением добавления новых слоев до завершения предыдущей анимации. Есть ли способ узнать, когда неявная анимация закончилась? Или в качестве альтернативы, если я использую CABasicAnimation
а также animationDidFinish
Есть ли способ узнать, какой объект закончил анимацию, когда animationDidFinish
называется?
3 ответа
Оказывается, вместо того, чтобы добавлять CABasicAnimation непосредственно в CALayer, мне пришлось добавить его в словарь "действий" слоя... Это оставляет слой в его окончательном положении после окончания анимации, но все равно вызывает метод 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);
}
}
}
А потом...
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
animating = NO;
}
Вы можете установить произвольные значения для ключей вашего объекта анимации. Это означает, что вы можете связать анимируемый слой с анимацией, а затем запросить его в -animationDidStop: done: анимацию создайте следующим образом:
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
// set other fields...
[anim setValue:layerToAnimate forKey:@"layer"];
// Start the animation
[layerToAnimate addAnimation:anim forKey:nil];
Затем проверьте это значение, когда анимация останавливается:
- (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];
}
Это явная анимация, но она должна дать вам то, что вам нужно.
Вы можете попробовать окружить свой код в CATransaction
, Вот как это будет выглядеть в Swift 3:
CATransaction.begin()
CATransaction.setCompletionBlock({
// run after the animations
})
// animtations
CATransaction.commit()