119 lines
3.3 KiB
Objective-C
119 lines
3.3 KiB
Objective-C
|
|
|
|
// Created by P on 2024/11/18.
|
|
|
|
|
|
#import "UIView+GradientLayer.h"
|
|
#import <QuartzCore/QuartzCore.h>
|
|
|
|
@implementation UIView (GradientLayer)
|
|
|
|
static NSString * const kGradientLayerName = @"GradientLayer";
|
|
static void *kGradientObserverKey = &kGradientObserverKey;
|
|
|
|
|
|
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
|
startPoint:(CGPoint)startPoint
|
|
endPoint:(CGPoint)endPoint
|
|
cornerRadius:(CGFloat)cornerRadius {
|
|
|
|
[self removeGradientBackground];
|
|
|
|
|
|
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
|
gradientLayer.name = kGradientLayerName;
|
|
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
|
gradientLayer.startPoint = startPoint;
|
|
gradientLayer.endPoint = endPoint;
|
|
gradientLayer.cornerRadius = cornerRadius;
|
|
|
|
|
|
gradientLayer.frame = self.bounds;
|
|
|
|
[self.layer insertSublayer:gradientLayer atIndex:0];
|
|
|
|
|
|
[self setupLayoutObserverForGradientLayer:gradientLayer];
|
|
}
|
|
|
|
|
|
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)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];
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
- (void)setupLayoutObserverForGradientLayer:(CAGradientLayer *)gradientLayer {
|
|
if (![self hasAddedObserver]) {
|
|
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:(__bridge void *)gradientLayer];
|
|
[self setHasAddedObserver:YES];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
ofObject:(id)object
|
|
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
|
context:(void *)context {
|
|
if ([keyPath isEqualToString:@"bounds"]) {
|
|
CAGradientLayer *gradientLayer = (__bridge CAGradientLayer *)context;
|
|
gradientLayer.frame = self.bounds;
|
|
} else {
|
|
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
}
|
|
}
|
|
|
|
|
|
- (NSArray *)cgColorsFromUIColors:(NSArray<UIColor *> *)colors {
|
|
NSMutableArray *cgColors = [NSMutableArray array];
|
|
for (UIColor *color in colors) {
|
|
[cgColors addObject:(id)color.CGColor];
|
|
}
|
|
return [cgColors copy];
|
|
}
|
|
|
|
|
|
- (BOOL)hasAddedObserver {
|
|
return [objc_getAssociatedObject(self, kGradientObserverKey) boolValue];
|
|
}
|
|
|
|
|
|
- (void)setHasAddedObserver:(BOOL)added {
|
|
objc_setAssociatedObject(self, kGradientObserverKey, @(added), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
}
|
|
|
|
|
|
@end
|