// // UIView+QX.m // QXLive // // Created by 启星 on 2025/4/27. // #import "UIView+QX.h" static const void* tagValue = &tagValue; @implementation UIView (QX) - (void)setX:(CGFloat)x { CGRect frame = self.frame; frame.origin.x = x; self.frame = frame; } - (void)setY:(CGFloat)y { CGRect frame = self.frame; frame.origin.y = y; self.frame = frame; } - (CGFloat)x { return self.frame.origin.x; } - (CGFloat)y { return self.frame.origin.y; } - (void)setCenterX:(CGFloat)centerX { CGPoint center = self.center; center.x = centerX; self.center = center; } - (CGFloat)centerX { return self.center.x; } - (void)setCenterY:(CGFloat)centerY{ CGPoint center = self.center; center.y = centerY; self.center = center; } - (CGFloat)centerY { return self.center.y; } - (void)setWidth:(CGFloat)width { CGRect frame = self.frame; frame.size.width = width; self.frame = frame; } - (void)setHeight:(CGFloat)height { CGRect frame = self.frame; frame.size.height = height; self.frame = frame; } - (CGFloat)height { return self.frame.size.height; } - (CGFloat)width { return self.frame.size.width; } - (void)setSize:(CGSize)size { CGRect frame = self.frame; frame.size = size; self.frame = frame; } - (CGSize)size { return self.frame.size; } - (void)setOrigin:(CGPoint)origin { CGRect frame = self.frame; frame.origin = origin; self.frame = frame; } - (CGPoint)origin { return self.frame.origin; } - (CGFloat)top { return self.frame.origin.y; } - (void)setTop:(CGFloat)top { CGRect frame = self.frame; frame.origin.y = top; self.frame = frame; } - (CGFloat)left { return self.frame.origin.x; } - (void)setLeft:(CGFloat)left { CGRect frame = self.frame; frame.origin.x = left; self.frame = frame; } - (CGFloat)bottom { return self.frame.size.height + self.frame.origin.y; } - (void)setBottom:(CGFloat)bottom { CGRect frame = self.frame; frame.origin.y = bottom - frame.size.height; self.frame = frame; } - (CGFloat)right { return self.frame.size.width + self.frame.origin.x; } - (void)setRight:(CGFloat)right { CGRect frame = self.frame; frame.origin.x = right - frame.size.width; self.frame = frame; } #pragma mark - 快速添加阴影 - (void)addProjectionWithShadowOpacity:(CGFloat)shadowOpacity { self.layer.shadowColor = [UIColor blackColor].CGColor;//shadowColor阴影颜色 self.layer.shadowOffset = CGSizeMake(0,0);//shadowOffset阴影偏移,x向右偏移2,y向下偏移6,默认(0, -3),这个跟shadowRadius配合使用 self.layer.shadowOpacity = shadowOpacity;//阴影透明度,默认0 self.layer.shadowRadius = 3;//阴影半径,默认3 } - (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius{ CALayer *subLayer = [CALayer layer]; subLayer.frame = self.frame; subLayer.cornerRadius = radius; subLayer.masksToBounds = NO; subLayer.backgroundColor = color.CGColor; subLayer.shadowColor = color.CGColor;//shadowColor阴影颜色 subLayer.shadowOffset = CGSizeMake(0,2); subLayer.shadowOpacity = 0.5;//阴影透明度,默认0 subLayer.shadowRadius = radius;//阴影半径,默认3 [self.layer insertSublayer:subLayer below:self.layer]; } - (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius frame:(CGRect)frame{ CALayer *subLayer = [CALayer layer]; subLayer.frame = frame; subLayer.cornerRadius = radius; subLayer.masksToBounds = YES; subLayer.backgroundColor = color.CGColor; subLayer.shadowColor = color.CGColor;//shadowColor阴影颜色 subLayer.shadowOffset = CGSizeMake(0,-3); subLayer.shadowOpacity = 0.5;//阴影透明度,默认0 subLayer.shadowRadius = radius;//阴影半径,默认3 [self.layer insertSublayer:subLayer below:self.layer]; } - (void)addBorderWithWidth:(CGFloat)width { self.layer.borderWidth = width; self.layer.borderColor = [UIColor blackColor].CGColor; } - (void)addBorderWithWidth:(CGFloat)width borderColor:(UIColor *)borderColor { self.layer.borderWidth = width; self.layer.borderColor = borderColor.CGColor; } - (void)addRoundedCornersWithRadius:(CGFloat)radius { self.layer.cornerRadius = radius; self.layer.masksToBounds = YES; } - (void)addRoundedCornersWithRadius:(CGFloat)radius byRoundingCorners:(UIRectCorner)corners{ UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setTopToBottomGradientBackgroundWithColors:(NSArray *)colors { [self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1)]; } - (void)setLeftToRightGradientBackgroundWithColors:(NSArray *)colors { [self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5)]; } - (void)setGradientBackgroundWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint { NSMutableArray *colorsM = [NSMutableArray array]; for (UIColor *color in colors) { [colorsM addObject:(__bridge id)color.CGColor]; } CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.colors = colorsM; gradientLayer.locations = @[@0, @1]; gradientLayer.startPoint = startPoint; gradientLayer.endPoint = endPoint; gradientLayer.frame = self.bounds; // [self.layer addSublayer:gradientLayer]; //layout中重复添加CAGradientLayer,需要清空多余的渐变层 NSArray *subLayers = self.layer.sublayers; NSArray *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { return [evaluatedObject isKindOfClass:[CAGradientLayer class]]; }]]; [removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj removeFromSuperlayer]; }]; [self.layer insertSublayer:gradientLayer atIndex:0]; } - (void)setLeftToRightGradientBackgroundWithColors:(NSArray *)colors roundedCorners:(CGFloat)radius { NSMutableArray *colorsM = [NSMutableArray array]; for (UIColor *color in colors) { [colorsM addObject:(__bridge id)color.CGColor]; } CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.colors = colorsM; gradientLayer.locations = @[@0, @1]; gradientLayer.startPoint = CGPointMake(0, 0.5); gradientLayer.endPoint = CGPointMake(1, 0.5); gradientLayer.frame = self.bounds; gradientLayer.cornerRadius = radius; gradientLayer.masksToBounds = YES; //layout中重复添加CAGradientLayer,需要清空多余的渐变层 NSArray *subLayers = self.layer.sublayers; NSArray *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { return [evaluatedObject isKindOfClass:[CAGradientLayer class]]; }]]; [removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj removeFromSuperlayer]; }]; [self.layer insertSublayer:gradientLayer atIndex:0]; } - (void)setAroundRoundedCorners:(CGFloat)radius { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setTopRoundedCorners:(CGFloat)radius { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setBottomRoundedCorners:(CGFloat)radius { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setLeftRoundedCorners:(CGFloat)radius { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } #pragma mark - 按Frame计算 - (void)setTopToBottomGradientBackgroundWithColors:(NSArray *)colors frame:(CGRect)frame { [self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) frame:frame]; } - (void)setLeftToRightGradientBackgroundWithColors:(NSArray *)colors frame:(CGRect)frame { [self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5) frame:frame]; } - (void)setGradientBackgroundWithColors:(NSArray *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint frame:(CGRect)frame { NSMutableArray *colorsM = [NSMutableArray array]; for (UIColor *color in colors) { [colorsM addObject:(__bridge id)color.CGColor]; } CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.colors = colorsM; gradientLayer.locations = @[@0, @1]; gradientLayer.startPoint = startPoint; gradientLayer.endPoint = endPoint; gradientLayer.frame = frame; // [self.layer addSublayer:gradientLayer]; //layout中重复添加CAGradientLayer,需要清空多余的渐变层 NSArray *subLayers = self.layer.sublayers; NSArray *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { return [evaluatedObject isKindOfClass:[CAGradientLayer class]]; }]]; [removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj removeFromSuperlayer]; }]; [self.layer insertSublayer:gradientLayer atIndex:0]; } - (void)setLeftToRightGradientBackgroundWithColors:(NSArray *)colors roundedCorners:(CGFloat)radius frame:(CGRect)frame { NSMutableArray *colorsM = [NSMutableArray array]; for (UIColor *color in colors) { [colorsM addObject:(__bridge id)color.CGColor]; } CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.colors = colorsM; gradientLayer.locations = @[@0, @1]; gradientLayer.startPoint = CGPointMake(0, 0.5); gradientLayer.endPoint = CGPointMake(1, 0.5); gradientLayer.frame = frame; gradientLayer.cornerRadius = radius; gradientLayer.masksToBounds = YES; //layout中重复添加CAGradientLayer,需要清空多余的渐变层 NSArray *subLayers = self.layer.sublayers; NSArray *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { return [evaluatedObject isKindOfClass:[CAGradientLayer class]]; }]]; [removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj removeFromSuperlayer]; }]; [self.layer insertSublayer:gradientLayer atIndex:0]; } - (void)setAroundRoundedCorners:(CGFloat)radius frame:(CGRect)frame { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = frame; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setTopRoundedCorners:(CGFloat)radius frame:(CGRect)frame { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = frame; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setBottomRoundedCorners:(CGFloat)radius frame:(CGRect)frame { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = frame; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setLeftRoundedCorners:(CGFloat)radius frame:(CGRect)frame { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(radius, radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; maskLayer.frame = frame; maskLayer.path = maskPath.CGPath; self.layer.mask = maskLayer; } - (void)setViewShadowPathWithColor:(UIColor *)shadowColor shadowOpacity:(CGFloat)shadowOpacity shadowRadius:(CGFloat)shadowRadius shadowPathType:(ShadowPathType)shadowPathType shadowPathWidth:(CGFloat)shadowPathWidth { self.layer.masksToBounds = NO;//必须要等于NO否则会把阴影切割隐藏掉 self.layer.shadowColor = shadowColor.CGColor;// 阴影颜色 self.layer.shadowOpacity = shadowOpacity;// 阴影透明度,默认0 self.layer.shadowOffset = CGSizeZero;//shadowOffset阴影偏移,默认(0, -3),这个跟shadowRadius配合使用 self.layer.shadowRadius = shadowRadius;//阴影半径,默认3 CGRect shadowRect = CGRectZero; CGFloat originX,originY,sizeWith,sizeHeight; originX = 0; originY = 0; sizeWith = self.bounds.size.width; sizeHeight = self.bounds.size.height; if (shadowPathType == ShadowPathTop) { shadowRect = CGRectMake(originX, originY-shadowPathWidth/2, sizeWith, shadowPathWidth); }else if (shadowPathType == ShadowPathBottom){ shadowRect = CGRectMake(originY, sizeHeight-shadowPathWidth/2, sizeWith, shadowPathWidth); }else if (shadowPathType == ShadowPathLeft){ shadowRect = CGRectMake(originX-shadowPathWidth/2, originY, shadowPathWidth, sizeHeight); }else if (shadowPathType == ShadowPathRight){ shadowRect = CGRectMake(sizeWith-shadowPathWidth/2, originY, shadowPathWidth, sizeHeight); }else if (shadowPathType == ShadowPathCommon){ shadowRect = CGRectMake(originX-shadowPathWidth/2, 2, sizeWith+shadowPathWidth, sizeHeight+shadowPathWidth/2); }else if (shadowPathType == ShadowPathAround){ shadowRect = CGRectMake(originX-shadowPathWidth/2, originY-shadowPathWidth/2, sizeWith+shadowPathWidth, sizeHeight+shadowPathWidth); } UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:shadowRect]; self.layer.shadowPath = bezierPath.CGPath;//阴影路径 } - (void)setViewBackgroundColorWithColorArray:(NSArray *)colorArray scaleArray:(NSArray * __nullable)scaleArray direction:(SRGradientDirection)direction { /* layoutIfNeeded不一定会调用layoutSubviews方法。 setNeedsLayout一定会调用layoutSubviews方法(有延迟,在下一轮runloop结束前)。 如果想在当前runloop中立即刷新,调用顺序应该是: [self setNeedsLayout]; [self layoutIfNeeded]; */ [self setNeedsLayout]; [self layoutIfNeeded]; CAGradientLayer *gradinentlayer = [CAGradientLayer layer]; if (direction == SRGradientDirectionLeftToRight) { gradinentlayer.startPoint = CGPointMake(0, 0); gradinentlayer.endPoint = CGPointMake(1.0, 0); }else { gradinentlayer.startPoint = CGPointMake(0, 0); gradinentlayer.endPoint = CGPointMake(0, 1.0); } NSMutableArray *CGColorArray = [NSMutableArray new]; for (UIColor *color in colorArray) { [CGColorArray addObject:(__bridge id)color.CGColor]; } if (!scaleArray) { }else { gradinentlayer.locations = scaleArray; } gradinentlayer.colors = CGColorArray; gradinentlayer.frame = self.bounds; [self.layer addSublayer:gradinentlayer]; } - (void)tap{ if (self.tapAction) { self.tapAction(self); } } - (void)addTapBlock:(void(^)(id obj))tapAction{ self.tapAction = tapAction; if (![self gestureRecognizers]) { self.userInteractionEnabled = YES; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)]; [self addGestureRecognizer:tap]; } } -(void)setTapAction:(void (^)(id))tapAction { objc_setAssociatedObject(self, tagValue, tapAction, OBJC_ASSOCIATION_COPY_NONATOMIC); } -(void (^)(id))tapAction { return objc_getAssociatedObject(self, tagValue); } - (UIViewController *)viewController { id nextResponder = [self nextResponder]; while (nextResponder != nil) { if ([nextResponder isKindOfClass:[UIViewController class]]) { UIViewController *vc = (UIViewController *)nextResponder; return vc; } nextResponder = [nextResponder nextResponder]; } return nil; } - (UINavigationController *)navigationController { id nextResponder = [self nextResponder]; while (nextResponder != nil) { if ([nextResponder isKindOfClass:[UINavigationController class]]) { UINavigationController *vc = (UINavigationController *)nextResponder; return vc; } nextResponder = [nextResponder nextResponder]; } return nil; } @end