// // UIView+ConerRadius.m // sansanMassage_Consumer // // Created by YoMi on 2022/8/11. // #import "UIView+ConerRadius.h" #import "NSObject+Swizzle.h" #import @interface YMCornerRadiusModel : NSObject @property (nonatomic, assign) CGFloat radius; @property (nonatomic, assign) UIRectCorner corners; @property (nonatomic, assign) UIEdgeInsets inserts; @end @implementation YMCornerRadiusModel + (instancetype)modelWithRadius:(CGFloat)radius corners:(UIRectCorner)corners insets:(UIEdgeInsets)inserts { YMCornerRadiusModel *model = [[YMCornerRadiusModel alloc] init]; model.corners = corners; model.radius = radius; model.inserts = inserts; return model; } @end static void *ym_cornerRadiusMaskKey = &ym_cornerRadiusMaskKey; @implementation UIView (ConerRadius) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [self swizzleOriginalSelector:@selector(layoutSubviews) swizzleSelector:@selector(ym_layoutSubviews) isInstanceSelector:YES]; }); } - (void)addRectCorner:(UIRectCorner)corners radius:(CGFloat)radius { [self addRectCorner:corners radius:radius insets:UIEdgeInsetsZero]; } - (void)addRectCorner:(UIRectCorner)corners radius:(CGFloat)radius insets:(UIEdgeInsets)inserts { // 如果是这两个情况则直接移除圆角化 if ((corners == 0 || radius <= 0) && UIEdgeInsetsEqualToEdgeInsets(inserts, UIEdgeInsetsZero)) { [self removeCornerRadius]; return; } YMCornerRadiusModel *oldModel = [self ym_cornerRadius]; // 判断是否跟旧的圆角化数据一样 if (oldModel.corners == corners && oldModel.radius == radius && UIEdgeInsetsEqualToEdgeInsets(oldModel.inserts, inserts)) return; YMCornerRadiusModel *model = [YMCornerRadiusModel modelWithRadius:radius corners:corners insets:inserts]; objc_setAssociatedObject(self, ym_cornerRadiusMaskKey, model, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self updateCornerMaskLayer]; } - (void)removeCornerRadius { [self viewForMakeCornerRadius].layer.mask = nil; objc_setAssociatedObject(self, ym_cornerRadiusMaskKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self updateCornerMaskLayer]; } - (YMCornerRadiusModel *)ym_cornerRadius { return objc_getAssociatedObject(self, ym_cornerRadiusMaskKey); } - (void)ym_layoutSubviews { [self ym_layoutSubviews]; YMCornerRadiusModel *cornerModel = [self ym_cornerRadius]; if (cornerModel != nil) { [self updateCornerMaskLayer]; } } - (CAShapeLayer *)maskLayerForModel:(YMCornerRadiusModel *)model { if (model == nil) return nil; CGRect bounds = self.bounds; bounds.size.width -= model.inserts.left + model.inserts.right; bounds.size.height -= model.inserts.top + model.inserts.bottom; UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:model.corners cornerRadii:CGSizeMake(model.radius, model.radius)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = CGRectMake(model.inserts.left, model.inserts.top, bounds.size.width, bounds.size.height); maskLayer.path = maskPath.CGPath; return maskLayer; } - (void)updateCornerMaskLayer { self.layer.mask = [self maskLayerForModel:[self ym_cornerRadius]]; } - (UIView *)viewForMakeCornerRadius { return self; } @end