思路:GradientLayer + CABasicAnimartion(keypath:locations)
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame=self.titleLabel.frame;
layer.startPoint = CGPointMake(0, 1);
layer.endPoint = CGPointMake(1, 1);
layer.colors = @[(__bridge id)[UIColor colorWithHexString:@"7D21FF"].CGColor,(__bridge id)[UIColor colorWithHexString:@"FFBF34"].CGColor,(__bridge id)[UIColor colorWithHexString:@"7D21FF"].CGColor];
layer.locations = @[@(0.0),@(0.2),@(1.0)];
[self.scrollView.layeraddSublayer:layer];
layer.mask=self.titleLabel.layer;
self.titleLabel.frame= layer.bounds;
CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"locations"];
ani.duration=1.f;
ani.toValue = @[@(0.0),@(1.0),@(0.0)];
ani.removedOnCompletion = NO;
ani.fillMode = kCAFillModeForwards;
ani.repeatCount=CGFLOAT_MAX;
[layeraddAnimation:aniforKey:nil];
注意:用label去裁剪渐变层,
//一旦把label层设置为mask层,label层就不能显示了,会直接从父层中移除,然后作为渐变层的mask层,且label层的父层会指向渐变层,这样做的目的:以渐变层为坐标系,方便计算裁剪区域,如果以其他层为坐标系,还需要做点的转换,需要把别的坐标系上的点,转换成自己坐标系上点,判断当前点在不在裁剪范围内,比较麻烦。
gradientLayer.mask=titleLabel.layer;
// 父层改了,坐标系也就改了,需要重新设置label的位置,才能正确的设置裁剪区域。
titleLabel.frame=gradientLayer.bounds;
还有一点需要注意的是,如果是xib上的label 要做这种效果 则不能设置约束,需要提前手动给定一个frame