CALayer: обратный вызов, когда анимация заканчивается? - PullRequest
0 голосов
/ 15 июня 2010

У меня возникли некоторые проблемы с анимацией нескольких слоев CAL в одно и то же время, и я надеялся, что кто-нибудь может указать мне правильное направление.

Мое приложение содержит массив CALayer.Положение каждого слоя установлено на (previousLayer.position.y + previousLayer.bounds.height), что в основном выкладывает их аналогично таблице.Затем у меня есть метод, который при каждом вызове добавляет новый слой в стек и устанавливает его позицию Y равной 0. Y позиции всех других слоев в массиве затем смещаются на высоту новогослой (по сути, толкая все старые слои вниз).

У меня проблемы с предотвращением добавления новых слоев до завершения предыдущей анимации.Есть ли способ узнать, когда неявная анимация закончилась?Или, в качестве альтернативы, если я использую CABasicAnimation и animationDidFinish, есть ли способ узнать, какой объект завершил анимацию при вызове animationDidFinish?

Ответы [ 3 ]

4 голосов
/ 15 июня 2010

Вы можете установить произвольные значения для ключей на вашем объекте анимации.Это означает, что вы можете связать анимируемый слой с анимацией, а затем запросить его в -animationDidStop: finish: анимация создается следующим образом:

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];
}

Это явная анимация, но она должна дать вам то, что вам нужно.

1 голос
/ 19 августа 2016

Вы можете попробовать окружить свой код CATransaction. Вот как это будет выглядеть в Swift 3:

CATransaction.begin()
CATransaction.setCompletionBlock({
  // run after the animations
})
// animtations
CATransaction.commit()
0 голосов
/ 26 июня 2010

Оказывается, что вместо того, чтобы добавлять 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; 
}
...