一、实现原理

  1. 因为需要实现渐变、动态的Label,所以这里最少涉及到3个组件,CAGradientLayer、 CABasicAnimation、UILabel
  2. 将UILabel作为CAGradientLayer的遮罩,然后给CAGradientLayer添加线性动画,即可实现渐变滚动效果

二、实现细节

  1. 假设当前是两种颜色横向渐变,则
CAGradientLayer *layer = [CAGradientLayer new];
layer.startPoint = CGPointMake(0 ,0)
layer.endPoint = CGPointMake(1 ,0)
layer.locations = @[@(0.2),@(0.4),@(0.6),@(0.8)]

这里locations是每个颜色对应的位置,如果正常渐变,不需要动态,只需要两个元素,0.5、1就是平分两半的渐变。 但是如果需要动态,则需要考虑平移,归位,循环,所以两种颜色渐变的颜色排列应该如下

@[UIColor.redColor,UIColor.greenColor,UIColor.greenColor,UIColor.redColor]
  1. 渐变循环效果实现 因为需要循环效果,所以实际上layer的size要比实际显示区域大,如果是横向滚动,则宽度应该是3倍, 假设self.width = 100,layer的frame就是CGRectMake(-100 , 0 ,3 * width ,height)。 然后用CABasicAnimation去变换layer的locations,实现线性动画。
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
animation.fromValue = @[@(0),@(0.125),@(0.25),@(0.375)];
animation.toValue = @[@(0.625),@(0.75),@(0.875),@(1)];
animation.duration = 3.0;
animation.repeatCount = CGFLOAT_MAX;
animation.removedOnCompletion = NO
[layer addAnimation:animation forKey:@"Gradient"];

以上layer的循环滚动效果已经实现, fromValue和toValue分别对应layer的4个颜色的起始和结束位置,所以fromValue、toValue、colors、positions数量一定要相等

  1. 渐变label遮罩 如果是静态渐变,label的frame正常设置即可,如果是动态渐变,因为layer的宽度是显示区域的3倍,所以label的x就应该是1倍的宽度。 以动态渐变为例,
    UILabel *label = [][UILabel alloc] initWithFrame:CGRectMake(100 , 0 , 100 ,height)];
    layer.mask = label.layer
    

三、demo和效果 效果见cu语音炫彩昵称 GradientLabel