//
//  ViewController.m
//  test_CAGradientLayer
//
//  Created by admin on 3/4/16.
//  Copyright © 2016 jeffasd. All rights reserved.
//

#import "ViewController.h"
#import "GardView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    GardView *view = [[GardView alloc] initWithFrame:CGRectMake(100, 300, 500, 50)];
//    view.frame = CGRectMake(100, 30, 50, 50);
    
    [self.view addSubview:view];
    
    [view setProgress:0.6];
    
    [view performAnimation];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end




//
//  GardView.h
//  test_CAGradientLayer
//
//  Created by admin on 3/4/16.
//  Copyright © 2016 jeffasd. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface GardView : UIView

- (void)setProgress:(CGFloat)value;

- (void)performAnimation;

@end
//
//  GardView.m
//  test_CAGradientLayer
//
//  Created by admin on 3/4/16.
//  Copyright © 2016 jeffasd. All rights reserved.
//

#import "GardView.h"

@interface GardView()

@property (nonatomic, strong) CALayer *maskLayer;
@property (nonatomic, assign) CGFloat progress;

@end

@implementation GardView


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

 Use a horizontal gradient
//CAGradientLayer *layer = (id)[self layer];
//[layer setStartPoint:CGPointMake(0.0, 0.5)];
//[layer setEndPoint:CGPointMake(1.0, 0.5)];
//
 Create colors using hues in +5 increments
//NSMutableArray *colors = [NSMutableArray array];
//for (NSInteger hue = 0; hue <= 360; hue += 5) {
//    
//    UIColor *color;
//    color = [UIColor colorWithHue:1.0 * hue / 360.0
//                       saturation:1.0
//                       brightness:1.0
//                            alpha:1.0];
//    [colors addObject:(id)[color CGColor]];
//}
//
//[layer setColors:[NSArray arrayWithArray:colors]];

- (instancetype)initWithFrame:(CGRect)frame{
    
    self = [super initWithFrame:frame];
    
    if (self != nil) {
        
        _maskLayer = [CALayer layer];
        [_maskLayer setFrame:CGRectMake(0, 0, 0, frame.size.height)];
        [_maskLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
        [self.layer setMask:_maskLayer];
        
        // Use a horizontal gradient
        CAGradientLayer *layer = (id)[self layer];
        [layer setStartPoint:CGPointMake(0.0, 0.5)];
        [layer setEndPoint:CGPointMake(1.0, 0.5)];
        
        // Create colors using hues in +5 increments
        NSMutableArray *colors = [NSMutableArray array];
        for (NSInteger hue = 0; hue <= 360; hue += 5) {
            
            UIColor *color;
            color = [UIColor colorWithHue:1.0 * hue / 360.0
                               saturation:1.0
                               brightness:1.0
                                    alpha:1.0];
            [colors addObject:(id)[color CGColor]]; 
        } 
        [layer setColors:[NSArray arrayWithArray:colors]];
    }
    
    return self;
}

- (void)performAnimation {
    // Move the last color in the array to the front
    // shifting all the other colors.
    CAGradientLayer *layer = (id)[self layer];
    NSMutableArray *mutable = [[layer colors] mutableCopy];
    id lastColor = [mutable lastObject] ;
    [mutable removeLastObject];
    [mutable insertObject:lastColor atIndex:0];

    NSArray *shiftedColors = [NSArray arrayWithArray:mutable];

    
    // Update the colors on the model layer
    [layer setColors:shiftedColors];
    
    // Create an animation to slowly move the gradient left to right.
    CABasicAnimation *animation;
    animation = [CABasicAnimation animationWithKeyPath:@"colors"];
    [animation setToValue:shiftedColors];
    [animation setDuration:0.08];
    [animation setRemovedOnCompletion:YES];
    [animation setFillMode:kCAFillModeForwards];
    [animation setDelegate:self];
    [layer addAnimation:animation forKey:@"animateGradient"];
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    [self performAnimation];
}

- (void)setProgress:(CGFloat)value {
    if (_progress != value) {
        // Progress values go from 0.0 to 1.0
        _progress = MIN(1.0, fabs(value));
        [self setNeedsLayout];
    }
}

- (void)layoutSubviews {
    // Resize our mask layer based on the current progress
    CGRect maskRect = [_maskLayer frame];
    maskRect.size.width = CGRectGetWidth([self bounds]) * _progress;
    [_maskLayer setFrame:maskRect];
}

@end


参考文章:

http://www.cocoachina.com/industry/20140705/9039.html