logo

Gavin Lee

春节

CAGradientLayer的应用-渐变进度条

2015-12-10 Views iOS | 动画692字3 min read

分享是一种美德。
座右铭:以前总以为坚持会让我们强大。

✍️ 开始

很久没写博客了,只要一停下来就很难在坚持,是要好好总结下最近工作内容,分享给大家。正在往大神方向一步一步走着。。。
   先看看效果:

图1.gif
图2.gif

其实很简单,要用到UIViewCALayer,CAGradientLayerCALayer的一个子类.
我们将是使用CAGradientLayer的一些属性:colors, startPoint, endPointmask
说道startPointendPoint 我们必须明白iOS系统中CALayer的坐标系统:

图3.png

先创建UIView的一个子类GradualProgressView,并且重写
- (instancetype)initWithFrame:(CGRect )frame:方法。
在初始化方法中创建对象并且确认坐标系,坐标系不同的值有不同的效果,自己可以尝试下:

CAGradientLayer *layer = (CAGradientLayer *)[self layer];
[layer setStartPoint:CGPointMake(0.0, 0.5)];
[layer setEndPoint:CGPointMake(1.0, 0.5)];

然后创建颜色渐变的UIColor对象并且用数组保存起来赋值给CAGradientLayercolors属性:

NSMutableArray *colorsArray = [NSMutableArray array];
for (NSInteger i = 0; i <= 360; i += 5) {
  UIColor *color = [UIColor colorWithHue:1.0 * i / 360
                              saturation:1.0
                              brightness:1.0
                                   alpha:1.0];
  [colorsArray addObject:(id)[color CGColor]];
}
[layer setColors:[NSArray arrayWithArray:colorsArray]];

现在运行的效果是:

图4.png

现在要添加一个移动的动画,我们可以获取CAGradientLayercolors属性改变数组里面的顺序,并添加上动画:

CAGradientLayer *layer = (CAGradientLayer *)[self layer];
NSMutableArray *colorArray = [[layer colors] mutableCopy];
UIColor *lastColor = [colorArray lastObject];
[colorArray removeLastObject];
[colorArray insertObject:lastColor atIndex:0];
NSArray *shiftedColors = [NSArray arrayWithArray:colorArray];
[layer setColors:shiftedColors];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"gavin_colors"];
[animation setToValue:shiftedColors];
[animation setDuration:0.08];
[animation setFillMode:kCAFillModeForwards];
[animation setDelegate:self];
[layer addAnimation:animation forKey:@"gavin_animateGradient"];

为了移动动画可以一直持续,我们要设置动画的代理,并实现动画结束的代理方法,并在结束方法中在重复执行上面的动作。就实现了持续移动的动画。

动画结束的代理方法:
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag

并在初始化方法中触发动画的开始。

为了实现进度,我们需要增加二个属性,maskLayer用来遮挡和 progress留给用户设置当前进度:

/**  Progress values go from 0.0 to 1.0  */
@property (nonatomic, assign) CGFloat progress;
/**  遮挡层  */
@property (nonatomic, strong) CALayer *maskLayer;

初始化遮挡层并利用CAGradientLayermask属性实现遮挡:

self.maskLayer = [CALayer layer];
[self.maskLayer setFrame:CGRectMake(0.0, 0.0, 0.0, frame.size.height)];
[self.maskLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[layer setMask:self.maskLayer];

当用户修改progress属性的值时我们要做相对应的改变,代码如下:

- (void)setProgress:(CGFloat)value {
  if (_progress != value) {
    _progress = MIN(1.0, fabs(value));
    [self setNeedsLayout];
  }
}
- (void)layoutSubviews {
  CGRect maskRect = [self.maskLayer frame];
  maskRect.size.width = CGRectGetWidth(self.bounds) * self.progress;
  [self.maskLayer setFrame:maskRect];
}

🌛 结束

这样就基本完成了,我们只需要创建GradualProgressView对象,就实现颜色渐变的进度条了。有什么不对的地方多多指教。希望大家多多关注我Git 。
最后附上具体的项目:ColorGradualProgress

EOF