【问题标题】:CALayer moves instantly when trying to animate?尝试制作动画时,CALayer 会立即移动?
【发布时间】:2010-07-22 18:55:57
【问题描述】:

下面的代码处理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;
    }
}

【问题讨论】:

    标签: iphone animation core-animation core-graphics calayer


    【解决方案1】:

    你已经很接近了。我只想将循环中的代码更改为:

    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 传递一些延迟,这将允许它有机会排队等待稍后的运行循环迭代。

    【讨论】:

      【解决方案2】:

      您必须在动画中设置新的图层位置,而不是直接在图层上。

      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"]
      

      【讨论】:

      • 问题是你勾勒的是一个明确的动画,当动画结束时,图层会恢复到原来的位置。
      猜你喜欢
      • 2010-09-18
      • 2020-08-26
      • 2011-11-05
      • 2012-01-09
      • 2013-11-10
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2016-04-03
      相关资源
      最近更新 更多