2010-07-22 48 views
0

下面的代碼處理一堆CALayers。每次將新圖層推入堆疊時,該功能都會被鎖定,並且所有現有圖層都會在屏幕上向下移動,以便爲新圖層騰出空間。一旦最後一層完成動畫,該功能將再次解鎖,以便可以推送新圖層。CALayer試圖動畫時會立即移動?

我的問題是每次這段代碼在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; 
    } 
} 

回答

3

你很近。我只想改變你的代碼迴路這樣:

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

這很好用!謝謝! – carloe 2010-07-22 23:02:00

-1

您必須在動畫中設置新的圖層位置,而不是直接在圖層上。

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

問題是,你所概述的是一個明確的動畫,當動畫結束時,圖層會恢復到它的原點位置。 – carloe 2010-07-22 20:40:07