0

I have one this scenario:

  1. I add to a layer CAAnimation that transforms it to a specific frame. with a starting time of 0.
  2. Then I add another CAAnimation that transforms it to a different frame. with a starting time of 0.5.

what happens is that the layer immediately gets the second frame (with no animation) and after the first animation time passes the second animation is completed correctly.

This is the animation creation code:

+ (CAAnimation *)transformAnimation:(CALayer *)layer
                          fromFrame:(CGRect)fromFrame
                            toFrame:(CGRect)toFrame
                          fromAngle:(CGFloat)fromAngle
                            toAngle:(CGFloat)toAngle
                             anchor:(CGPoint)anchor
                           vertical:(BOOL)vertical
                              begin:(CFTimeInterval)begin
                           duration:(CFTimeInterval)duration {

    CATransform3D fromTransform = makeTransform(layer, fromFrame, fromAngle, anchor, vertical);
    CATransform3D midTransform1 = makeTransformLerp(layer, fromFrame, toFrame, fromAngle, toAngle, anchor, 0.33, vertical);
    CATransform3D midTransform2 = makeTransformLerp(layer, fromFrame, toFrame, fromAngle, toAngle, anchor, 0.66, vertical);
    CATransform3D toTransform = makeTransform(layer, toFrame, toAngle, anchor, vertical);

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    animation.values = @[[NSValue valueWithCATransform3D:fromTransform],
                         [NSValue valueWithCATransform3D:midTransform1],
                         [NSValue valueWithCATransform3D:midTransform2],
                         [NSValue valueWithCATransform3D:toTransform]
                         ];
    animation.beginTime = begin;
    animation.duration = duration;
    animation.fillMode = kCAFillModeBoth;
    animation.calculationMode = kCAAnimationPaced;
    animation.removedOnCompletion = NO;
    return animation;
}

EDIT in most scenarios, this code works well and the animations are sequenced correctly. But if I set 1 transform animation to start after 2 seconds and then set another transform to start after 4 seconds. the first transform is applied immediately to the layer and the second animation starts from there.

Any Idea how can I separate the animation to run one after the other? (I prefer not using a completion block)

Thanks

shannoga
  • 19,649
  • 20
  • 104
  • 169
  • Can you give a little code of what you are wanting or doing and I would be glad to help. – agibson007 Jul 29 '18 at 19:44
  • Begin time alone would do that. Can you give some more context sorry. – agibson007 Jul 29 '18 at 20:38
  • @agibson007 Edited the question, thanks – shannoga Jul 29 '18 at 20:45
  • k. Can you also share the lines where you add this to your layer. I think I have your answer but want to be sure. Am I understanding your right that you would want them to act in sequence. meaning if you start an animation with 0.5 seconds duration and another one at a begin time of 0.4 with a 0.5 duration you don't really want it to start until 0.5 and then continue with a 0.5 duration? Just trying to make sure. – agibson007 Jul 30 '18 at 14:26
  • Currently, I am not updating the modal layer. – shannoga Jul 30 '18 at 16:57
  • is my understanding of the problem correct in the comment above ? If not I don't really want to type out Obj C code until I know. You want the newest animation to wait if it intersects with the time of the current animation. If so I have the answer in Swift but would need to convert it to Obj C. – agibson007 Jul 30 '18 at 20:12
  • Did the answer below help the issue at all. If it is a matter of unknown begin times overlapping I can help with that but I think the Fillmode of both might have been the issue – agibson007 Aug 07 '18 at 15:08

1 Answers1

0

The easiest and most glaring early fix would be to change the fill mode so that the second animation is not clamped on both ends overriding the previous animation.

animation.fillMode = kCAFillModeForwards;

Also I would adjust the begin time to be

animation.beginTime = CACurrentMediaTime() + begin;

If it is a matter of overlapping begin times and durations and not this let me know and I can provide that as well.

agibson007
  • 4,173
  • 2
  • 19
  • 24