0

I am using block code to create a horizontal progress bar which reflects some data, data could be anything. It just takes a min value, a max value, and a current value which allows me to set up the animation, i.e min value 0, max value 100, currently value 50, the progress bar will fill up by 50%. I have a progress bar container with a view inside it, the view gets stretched while animating.

I have got the animation part working fine using block code, i.e.

[UIView animateWithDuration:3.0
                              delay:0.0f
                            options:UIViewAnimationCurveEaseInOut
                         animations:^(void)
         {
             progressView.frame = CGRectMake(progressView.frame.origin.x,progressView.frame.origin.y,iWidth,progressView.frame.size.height);

         }
                         completion:^(BOOL finished)
         {

         }]; 

What I want to do is while this is animating, to slowly change the gradient by inserting sublayers, quick example

    (This method will be called on a timer, the idea is to slowly change the gradient
    after 0.5 seconds for example)
    CAGradientLayer *testLayer = [BackgroundLayer customGradient:iRedValue :iGreenValue :0];
    testLayer.frame = progressView.bounds;
    [progressView.layer insertSublayer:testLayer atIndex:1];

(The background layer is just a custom class I have which allows users to create a custom gradient colour using RGB values). The idea is, I would keep inserting sub layers slowly changing the gradient as the progressView finishes animating. The idea is that the view starts off one colour, say green, and the further along the bar animates, it changes colour to amber, then red if it reaches maximum.

When I add the sublayer the animation just jumps to the end, because testLayer takes on the width of the progressView after it is finished animating, and adds it. I want this to happen slowly over the course of the animation.

Any ideas on how I would go about doing this?

Thanks in advance!

4

1 回答 1

2

Small example of Animationg colors of a CAGradientLayer

@interface GradientAnimationView : UIView

@end

@implementation GradientAnimationView {
    NSArray *_colorsFirst;
    NSArray *_colorsSecond;
    NSArray *_currentColor;
}

+ (Class)layerClass {
    return [CAGradientLayer class];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        CAGradientLayer *layer = (CAGradientLayer *)[self layer];
        _colorsFirst = @[(__bridge id)[[UIColor blueColor] CGColor], (__bridge id)[[UIColor greenColor] CGColor]];
        _colorsSecond = @[(__bridge id)[[UIColor redColor] CGColor], (__bridge id)[[UIColor yellowColor] CGColor]];
        _currentColor = _colorsFirst;
        [layer setColors:_colorsFirst];
    }
    return self;
}

- (void)animateColors {
    if (_currentColor == _colorsSecond) {
        _currentColor = _colorsFirst;
    } else {
        _currentColor = _colorsSecond;
    }

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"colors"];
    anim.fromValue = [[self layer] valueForKey:@"colors"];
    anim.toValue = _currentColor;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.duration = 0.4;
    anim.delegate = self;

    [self.layer addAnimation:anim forKey:@"colors"];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self animateColors];
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    CAGradientLayer *layer = (CAGradientLayer *)[self layer];
    [layer setColors:_currentColor];
}

@end
于 2013-01-23T12:30:39.280 回答