CALayer движется мгновенно при попытке анимации? - PullRequest
0 голосов
/ 22 июля 2010

Код ниже обрабатывает стек CALayers.Каждый раз, когда новый слой помещается в стек, функция блокируется, и все существующие слои перемещаются вниз по экрану, чтобы освободить место для нового слоя.Как только последний слой завершен, анимация функции снова разблокирована, чтобы можно было выдвигать новые слои.

Моя проблема в том, что каждый раз, когда этот код запускает начальную анимацию на newLayer.Другими словами, вместо того, чтобы позиционировать новый слой на CGPointMake(0, 0-offset) и затем анимировать его на CGPointMake(0, currentLayer.position.y + offset), он мгновенно появляется в своей конечной позиции.Я что-то пропустил?Спасибо!

-(void)addNewLayerWithHeight:(float)layerHeight {
    if(!animationLocked) {
        animationLocked = YES;
        //Offset is the ammount that each existing layer will need to be moved down by
        int offset = layerHeight;

        //Create the new layer
        CALayer *newLayer = [CALayer layer];
        [newLayer setBounds:CGRectMake(0, 0, self.view.layer.bounds.size.width, layerHeight)];
        [newLayer setAnchorPoint:CGPointMake(0, 0)];
        [newLayer setPosition:CGPointMake(0, 0-offset)];
        [newLayer setBackgroundColor:[[UIColor redColor] CGColor]];

        //Add the new layer to the view's layer and to layerArray
        [self.view.layer addSublayer:newLayer];
        [layerArray insertObject:newLayer atIndex:0];

        //loop through all layers and move them to their new position...
        for(int i=0;i<[layerArray count]; i++) {
            CALayer *currentLayer = [layerArray objectAtIndex:i];

            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
            [anim setValue:@"stackLayer" forKey:@"kind"];
            [anim setValue:[NSNumber numberWithInt:i] forKey:@"index"];
            [anim setDelegate:self];
            [anim setDuration:1.0];

            currentLayer.actions = [NSDictionary dictionaryWithObject:anim forKey:@"position"];
            currentLayer.position = CGPointMake(0, currentLayer.position.y + offset);
        }
    }
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    //Make sure the last layer finished animating...
    if([[anim valueForKey:@"kind"] isEqual:@"stackLayer"] && [[anim valueForKey:@"index"] isEqual:[NSNumber numberWithInt:[layerArray count]-1]]) {
        animationLocked = NO;
    }
}

Ответы [ 2 ]

3 голосов
/ 23 июля 2010

Ты довольно близко. Я бы просто изменил ваш код в цикле так:

for(int i=0;i<[layerArray count]; i++)
{
  CALayer *currentLayer = [layerArray objectAtIndex:i];

  CGPoint endPoint = CGPointMake(0, currentLayer.position.y + offset);
  CGPoint currentPoint = [currentLayer position];

  CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
  [anim setFromValue:[NSValue valueWithCGPoint:currentPoint]];
  [anim setToValue:[NSValue valueWithCGPoint:endPoint]];
  [anim setDelegate:self];
  [anim setDuration:1.0];

  [anim setValue:@"stackLayer" forKey:@"kind"];
  [anim setValue:[NSNumber numberWithInt:i] forKey:@"index"];

  [currentLayer setPosition:endPoint];
  [currentLayer addAnimation:anim forKey:@"position"];
}

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

0 голосов
/ 22 июля 2010

Вы должны установить новую позицию слоя в анимации, а не непосредственно в слое.

CAlayer *layer = ...

CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation"];]
positionAnimation.fromValue = oldPOsition
positionAnimation.toValue = newPosition
positionAnimation.duration = n;
positionAnimation.delegate = self;          

[layerToAnimate addAnimation:layerAnimation forKey:@"transform.translation"]
...