Files
featherVoice/QXLive/Tools/Category/UIView+QX.m

509 lines
18 KiB
Mathematica
Raw Normal View History

2025-08-08 10:49:36 +08:00
//
// 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,x2y6(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<UIColor *> *)colors {
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1)];
}
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors {
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5)];
}
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *)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];
//layoutCAGradientLayer
NSArray<CALayer *> *subLayers = self.layer.sublayers;
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _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<UIColor *> *)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;
//layoutCAGradientLayer
NSArray<CALayer *> *subLayers = self.layer.sublayers;
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _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<UIColor *> *)colors frame:(CGRect)frame {
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) frame:frame];
}
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors frame:(CGRect)frame {
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5) frame:frame];
}
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *)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];
//layoutCAGradientLayer
NSArray<CALayer *> *subLayers = self.layer.sublayers;
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _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<UIColor *> *)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;
//layoutCAGradientLayer
NSArray<CALayer *> *subLayers = self.layer.sublayers;
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _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 {
/*
layoutIfNeededlayoutSubviews
setNeedsLayoutlayoutSubviewsrunloop
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