How can I chain Core Animations for different Layers one after the other?

前端 未结 3 813
野的像风
野的像风 2021-02-08 15:28

I have a scrollView with paging enabled and a number N of pages, which are UIViews as subviews of the scrollView.

I\'m trying to do the following:

User scrolls t

相关标签:
3条回答
  • 2021-02-08 15:41

    In Swift 3 (layers is an array of CALayer or CAShapeLayer)

    var timeOffset:Double = 0
    for layer in layers {
        let a = CABasicAnimation(keyPath: "path"
        a.fromValue = layer.ovalPathSmall.cgPath
        a.toValue = layer.ovalPathLarge.cgPath
        a.fillMode = kCAFillModeForwards
        a.beginTime = CACurrentMediaTime() + timeOffset
        a.duration = 0.3
        a.isRemovedOnCompletion = false
        layer.add(a, forKey: nil)
    
        timeOffset += 0.3
    }
    

    And in case you're wondering what ovalPathSmall and ovalPathLarge are:

    ovalPathSmall = UIBezierPath(arcCenter: position, radius: smallRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
    ovalPathLarge = UIBezierPath(arcCenter: position, radius: largeRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
    
    0 讨论(0)
  • 2021-02-08 15:59

    Actually, it turns out that the key is getting the current time in terms of a frame of reference and adding any time offset to that current time. This works also for non-grouped animations.

    For instance, something along the lines of this code would cause n layers (assumed to be stored in some array) to sequentially fade in one after the other, each taking .8 secs.:

    CGFloat timeOffset = 0;
    
    [CATransaction begin];
    
    for (CALayer *layer in layers) {
        CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"opacity"];
    
        a.fromValue = @(0);
        a.toValue = @(1);
        a.fillMode = kCAFillModeForwards;
        a.beginTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil] + timeOffset;
        a.duration = 0.8;
        a.removedOnCompletion = NO;
    
        [layer addAnimation:a forKey:nil];
    
        timeOffset += a.duration;
    }
    
    [CATransaction commit];
    

    In the above case, the frame of reference is simply the current time when the invocations take place.

    0 讨论(0)
  • 2021-02-08 16:04

    The beginTime property of a CAAnimation only seems to work if the CAAnimation is part of a CAAnimationGroup. I think you'll also need to set the duration property of the CAAnimationGroup large enough to last until its final animation completes.

    https://stackoverflow.com/a/563486/77567

    0 讨论(0)
提交回复
热议问题