CAGradientLayer闪动问题
场景:UICollectionView中的某个item上有一张图片,图片的底部需要展示渐变层,但是每个item上图片大小不一致。在item复用的时候,添加的CAGradientLayer会有明显的展现动画。
普通方法
图片初始约束
1 [_imageView mas_makeConstraints:^(MASConstraintMaker *make) { 2 make.top.mas_equalTo(0); 3 make.left.mas_equalTo(0); 4 make.right.mas_equalTo(0); 5 make.height.equalTo(self.imageView.mas_width); 6 }];
刷新或者复用约束
1 [_imageView mas_remakeConstraints:^(MASConstraintMaker *make) { 2 make.top.mas_equalTo(0); 3 make.left.mas_equalTo(0); 4 make.right.mas_equalTo(0); 5 make.height.equalTo(self.imageView.mas_width).multipliedBy(scale); 6 }];
CAGradientLayer初始设置
1 _gradientLayer = [[CAGradientLayer alloc] init]; 2 _gradientLayer.locations = @[@0, @1]; 3 _gradientLayer.startPoint = CGPointMake(0, 0); 4 _gradientLayer.endPoint = CGPointMake(0, 1); 5 _gradientLayer.colors = @[ 6 (__bridge id)[UIColor colorWithWhite:0 alpha:0].CGColor, 7 (__bridge id)[UIColor colorWithWhite:0 alpha:0.45].CGColor, 8 ]; 9 [_imageView.layer addSublayer:_gradientLayer];
CAGradientLayer更新frame
1 - (void)layoutSubviews { 2 [super layoutSubviews]; 3 4 _gradientLayer.frame = CGRectMake(0, CGRectGetHeight(_imageView.frame) - 20, CGRectGetWidth(_imageView.frame), 20); 5 }
改进方法
创建一个单独做渐变的View,而不是将CAGradientLayer添加到imageView的layer中
@interface FCGradientLayerView : UIView @end @implementation FCGradientLayerView + (Class)layerClass { return [CAGradientLayer class]; } @end
FCGradientLayerView的初始设置
1 _gradientLayerView = [[FCGradientLayerView alloc] init]; 2 _gradientLayerView.backgroundColor = UIColor.clearColor; 3 if ([_gradientLayerView.layer isKindOfClass:CAGradientLayer.class]) { 4 CAGradientLayer *gl = (CAGradientLayer *)_gradientLayerView.layer; 5 gl.locations = @[@0, @1]; 6 gl.startPoint = CGPointMake(0, 0); 7 gl.endPoint = CGPointMake(0, 1); 8 gl.colors = @[ 9 (__bridge id)[UIColor colorWithWhite:0 alpha:0].CGColor, 10 (__bridge id)[UIColor colorWithWhite:0 alpha:0.45].CGColor, 11 ]; 12 } 13 [_imageView addSubview:_gradientLayerView];
FCGradientLayerView的约束
1 [_gradientLayerView mas_makeConstraints:^(MASConstraintMaker *make) { 2 make.left.mas_equalTo(0); 3 make.bottom.mas_equalTo(0); 4 make.right.mas_equalTo(0); 5 make.height.mas_equalTo(20); 6 }];
可以看到是用更加方便,也解决了最开始的问题。
小结
解决方法非原创,记录这个问题是因为原始网站有风险,二次创作博客没看懂。原始见解决 CAGradientLayer 闪烁问题
浙公网安备 33010602011771号