Trying to delay CABasicAnimation position and opacity of layer by 3 seconds but

前端 未结 3 485
囚心锁ツ
囚心锁ツ 2021-02-08 13:50

I am trying to delay the animation of layer\'s opacity and position by 3 seconds using setBeginTime. I have called the layer boxLayer. The animation is going well however during

3条回答
  •  隐瞒了意图╮
    2021-02-08 14:51

    The problem is that you're setting the boxLayer properties of position and of opacity to their end values. You need to:

    1. Set the boxLayer properties to their starting values, not their ending values (this is why it's starting in the ending position/opacity ... usually if the animation starts immediately, this isn't an issue, but because you're deferring the start, using the ending positions is problematic);

    2. For your two animations, you have to change removedOnCompletion to NO and fillMode to kCAFillModeForwards (this is the correct way to keep it from reverting back to the original position upon completion).

    Thus:

    // Create an animation that will change the opacity of a layer
    CABasicAnimation *fader = [CABasicAnimation animationWithKeyPath:@"opacity"];
    
    // It will last 1 second and will be delayed by 3 seconds
    [fader setDuration:1.0];
    [fader setBeginTime:CACurrentMediaTime()+3.0];
    
    // The layer's opacity will start at 0.0 (completely transparent)
    [fader setFromValue:[NSNumber numberWithFloat:startOpacity]];
    
    // And the layer will end at 1.0 (completely opaque)
    [fader setToValue:[NSNumber numberWithFloat:endOpacity]];
    
    // MAKE SURE IT DOESN'T CHANGE OPACITY BACK TO STARTING VALUE    
    [fader setRemovedOnCompletion:NO];
    [fader setFillMode:kCAFillModeForwards];
    
    // Add it to the layer
    [boxLayer addAnimation:fader forKey:@"BigFade"];
    
    // SET THE OPACITY TO THE STARTING VALUE
    [boxLayer setOpacity:startOpacity];
    
    // Create an animation that will change the position of a layer
    CABasicAnimation *mover = [CABasicAnimation animationWithKeyPath:@"position"];
    
    // It will last 1 second and will be delayed by 3 seconds
    [mover setDuration:1.0];
    [mover setBeginTime:CACurrentMediaTime()+3.0];
    
    // Setting starting position
    [mover setFromValue:[NSValue valueWithCGPoint:CGPointMake(startX, startY)]];
    
    // Setting ending position
    [mover setToValue:[NSValue valueWithCGPoint:CGPointMake(endX, endY)]];
    
    // MAKE SURE IT DOESN'T MOVE BACK TO STARTING POSITION   
    [mover setRemovedOnCompletion:NO];
    [mover setFillMode:kCAFillModeForwards];
    
    // Add it to the layer
    [boxLayer addAnimation:mover forKey:@"BigMove"];
    
    // SET THE POSITION TO THE STARTING POSITION
    [boxLayer setPosition:CGPointMake(startX, startY)];
    

    Personally, I think you're doing a lot of work for something that's done far more easily with block-based animation on the view (for the purposes of this demonstration, I'm assuming your boxLayer is a CALayer for a control called box). You don't need Quartz 2D, either, if you do it this way:

    box.alpha = startOpacity;
    box.frame = CGRectMake(startX, startY, box.frame.size.width, box.frame.size.height);
    
    [UIView animateWithDuration:1.0
                          delay:3.0
                        options:0
                     animations:^{
                         box.alpha = endOpacity;
                         box.frame = CGRectMake(endX, endY, box.frame.size.width, box.frame.size.height);
                     }
                     completion:nil];
    

提交回复
热议问题