// // UIView+GradientLayer.m // YuMi // // Created by P on 2024/11/18. // #import "UIView+GradientLayer.h" #import @implementation UIView (GradientLayer) static NSString * const kGradientLayerName = @"GradientLayer"; static void *kGradientObserverKey = &kGradientObserverKey; // 添加渐变背景 - (void)addGradientBackgroundWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint cornerRadius:(CGFloat)cornerRadius { // 确保移除已有的渐变背景和 KVO 监听 [self removeGradientBackground]; // 创建渐变图层 CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.name = kGradientLayerName; gradientLayer.colors = [self cgColorsFromUIColors:colors]; gradientLayer.startPoint = startPoint; gradientLayer.endPoint = endPoint; gradientLayer.cornerRadius = cornerRadius; // 初次设置 frame gradientLayer.frame = self.bounds; [self.layer insertSublayer:gradientLayer atIndex:0]; // 添加 KVO 监听 [self setupLayoutObserverForGradientLayer:gradientLayer]; } // 动态更新渐变背景 - (void)updateGradientBackgroundWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint { CAGradientLayer *gradientLayer = [self gradientLayer]; if (gradientLayer) { gradientLayer.colors = [self cgColorsFromUIColors:colors]; gradientLayer.startPoint = startPoint; gradientLayer.endPoint = endPoint; } } // 移除渐变背景和监听 - (void)removeGradientBackground { // 移除渐变图层 CAGradientLayer *gradientLayer = [self gradientLayer]; if (gradientLayer) { [gradientLayer removeFromSuperlayer]; } // 移除 KVO 监听 if ([self hasAddedObserver]) { [self removeObserver:self forKeyPath:@"bounds"]; [self setHasAddedObserver:NO]; } } // 获取渐变图层 - (CAGradientLayer *)gradientLayer { for (CALayer *layer in self.layer.sublayers) { if ([layer.name isEqualToString:kGradientLayerName] && [layer isKindOfClass:[CAGradientLayer class]]) { return (CAGradientLayer *)layer; } } return nil; } // 添加 KVO 监听 - (void)setupLayoutObserverForGradientLayer:(CAGradientLayer *)gradientLayer { if (![self hasAddedObserver]) { [self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:(__bridge void *)gradientLayer]; [self setHasAddedObserver:YES]; } } // KVO 监听回调 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"bounds"]) { CAGradientLayer *gradientLayer = (__bridge CAGradientLayer *)context; gradientLayer.frame = self.bounds; // 更新渐变图层的 frame } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } // 工具方法:转换颜色数组 - (NSArray *)cgColorsFromUIColors:(NSArray *)colors { NSMutableArray *cgColors = [NSMutableArray array]; for (UIColor *color in colors) { [cgColors addObject:(id)color.CGColor]; } return [cgColors copy]; } // 工具方法:判断是否已注册 KVO - (BOOL)hasAddedObserver { return [objc_getAssociatedObject(self, kGradientObserverKey) boolValue]; } // 工具方法:设置是否已注册 KVO - (void)setHasAddedObserver:(BOOL)added { objc_setAssociatedObject(self, kGradientObserverKey, @(added), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end