zoukankan      html  css  js  c++  java
  • 圆角优化

    主要使用这二个分类,按常用排序。cell上圆角特别需要。不然一个好像0.2m(粗算)。一个项目个人认为上限50未优化,所以cell必须优化。

    1。UIImageView+CornerRadius

     

    2。UIView+RoundedCorner

         UIImage+RoundedCorner

    简单使用,记录下。

     

    UIView+RoundedCorner

     

    #import "UIView+RoundedCorner.h"
    #import <objc/runtime.h>
    
    static NSOperationQueue *jm_operationQueue;
    static char jm_operationKey;
    
    @implementation UIView (RoundedCorner)
    
    + (void)load {
        jm_operationQueue = [[NSOperationQueue alloc] init];
    }
    
    - (NSOperation *)jm_getOperation {
        id operation = objc_getAssociatedObject(self, &jm_operationKey);
        return operation;
    }
    
    - (void)jm_setOperation:(NSOperation *)operation {
        objc_setAssociatedObject(self, &jm_operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (void)jm_cancelOperation {
        NSOperation *operation = [self jm_getOperation];
        [operation cancel];
        [self jm_setOperation:nil];
    }
    
    - (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
        [self jm_setCornerRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:nil backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
        [self jm_setJMRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:nil backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setCornerRadius:(CGFloat)radius withBackgroundColor:(UIColor *)backgroundColor {
        [self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:backgroundColor backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withBackgroundColor:(UIColor *)backgroundColor {
        [self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:backgroundColor backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image {
        [self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image {
        [self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:UIViewContentModeScaleAspectFill];
    }
    
    - (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode {
        [self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:contentMode];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode {
        [self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:contentMode];
    }
    
    - (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode {
        [self jm_setJMRadius:JMRadiusMake(radius, radius, radius, radius) withBorderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage contentMode:contentMode];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode {
        [self jm_cancelOperation];
        
        [self jm_setJMRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage contentMode:contentMode size:CGSizeZero];
    }
    
    - (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode size:(CGSize)size {
        
        __block CGSize _size = size;
        
        __weak typeof(self) wself = self;
        NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
            
            if ([[wself jm_getOperation] isCancelled]) return;
            
            if (CGSizeEqualToSize(_size, CGSizeZero)) {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    _size = wself.bounds.size;
                });
            }
            
            CGSize size2 = CGSizeMake(pixel(_size.width), pixel(_size.height));
            
            UIImage *image = [UIImage jm_imageWithRoundedCornersAndSize:size2 JMRadius:radius borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage withContentMode:contentMode];
            
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                __strong typeof(wself) self = wself;
                if ([[self jm_getOperation] isCancelled]) return;
                
                self.frame = CGRectMake(pixel(self.frame.origin.x), pixel(self.frame.origin.y), size2.width, size2.height);
                if ([self isKindOfClass:[UIImageView class]]) {
                    ((UIImageView *)self).image = image;
                } else if ([self isKindOfClass:[UIButton class]] && backgroundImage) {
                    [((UIButton *)self) setBackgroundImage:image forState:UIControlStateNormal];
                } else if ([self isKindOfClass:[UILabel class]]) {
                    self.layer.backgroundColor = [UIColor colorWithPatternImage:image].CGColor;
                } else {
                    self.layer.contents = (__bridge id _Nullable)(image.CGImage);
                }
            }];
        }];
        
        [self jm_setOperation:blockOperation];
        [jm_operationQueue addOperation:blockOperation];
    }
    
    static inline float pixel(float num) {
        float unit = 1.0 / [UIScreen mainScreen].scale;
        double remain = fmod(num, unit);
        return num - remain + (remain >= unit / 2.0? unit: 0);
    }

    UIImage+RoundedCorner

    + (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit JMRadius:(JMRadius)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage withContentMode:(UIViewContentMode)contentMode {
        if (backgroundImage) {
            backgroundImage = [backgroundImage scaleToSize:CGSizeMake(sizeToFit.width, sizeToFit.height) withContentMode:contentMode backgroundColor:backgroundColor];
            backgroundColor = [UIColor colorWithPatternImage:backgroundImage];
        } else if (!backgroundColor){
            backgroundColor = [UIColor whiteColor];
        }
        
        UIGraphicsBeginImageContextWithOptions(sizeToFit, NO, UIScreen.mainScreen.scale);
    
        CGFloat halfBorderWidth = borderWidth / 2;
        //设置上下文
        CGContextRef context = UIGraphicsGetCurrentContext();
        //边框大小
        CGContextSetLineWidth(context, borderWidth);
        //边框颜色
        CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
        //矩形填充颜色
        CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
        CGFloat height = sizeToFit.height;
        CGFloat width = sizeToFit.width;
        radius = [UIImage transformationJMRadius:radius size:sizeToFit borderWidth:borderWidth];
        
        CGFloat startPointY;
        if (radius.topRightRadius >= height - borderWidth) {
            startPointY = height;
        } else if (radius.topRightRadius > 0){
            startPointY = halfBorderWidth + radius.topRightRadius;
        } else {
            startPointY = 0;
        }
        CGContextMoveToPoint(context, width - halfBorderWidth, startPointY);  // 开始坐标右边开始
        CGContextAddArcToPoint(context, width - halfBorderWidth, height - halfBorderWidth, width / 2, height - halfBorderWidth, radius.bottomRightRadius);  // 右下角角度
        CGContextAddArcToPoint(context, halfBorderWidth, height - halfBorderWidth, halfBorderWidth, height / 2, radius.bottomLeftRadius); // 左下角角度
        CGContextAddArcToPoint(context, halfBorderWidth, halfBorderWidth, width / 2, halfBorderWidth, radius.topLeftRadius); // 左上角
        CGContextAddArcToPoint(context, width - halfBorderWidth, halfBorderWidth, width - halfBorderWidth, height / 2, radius.topRightRadius); // 右上角
        CGContextDrawPath(context, kCGPathFillStroke); //根据坐标绘制路径
        
        UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return outImage;
    }

     

     

     

     

     

    UIImageView+CornerRadius

    #import "UIImageView+CornerRadius.h"
    #import <objc/runtime.h>
    
    const char kRadius;
    const char kRoundingCorners;
    const char kIsRounding;
    const char kHadAddObserver;
    const char kProcessedImage;
    
    const char kBorderWidth;
    const char kBorderColor;
    
    @interface UIImageView ()
    
    @property (assign, nonatomic) CGFloat radius;
    @property (assign, nonatomic) UIRectCorner roundingCorners;
    @property (assign, nonatomic) CGFloat borderWidth;
    @property (strong, nonatomic) UIColor *borderColor;
    @property (assign, nonatomic) BOOL hadAddObserver;
    @property (assign, nonatomic) BOOL isRounding;
    
    @end
    
    
    
    
    
    @implementation UIImageView (CornerRadius)
    
    /**
     * @brief init the Rounding UIImageView, no off-screen-rendered
     */
    - (instancetype)initWithRoundingRectImageView {
        self = [super init];
        if (self) {
            [self zy_cornerRadiusRoundingRect];
        }
        return self;
    }
    
    /**
     * @brief init the UIImageView with cornerRadius, no off-screen-rendered
     */
    - (instancetype)initWithCornerRadiusAdvance:(CGFloat)cornerRadius rectCornerType:(UIRectCorner)rectCornerType {
        self = [super init];
        if (self) {
            [self zy_cornerRadiusAdvance:cornerRadius rectCornerType:rectCornerType];
        }
        return self;
    }
    
    /**
     * @brief attach border for UIImageView with width & color
     */
    - (void)zy_attachBorderWidth:(CGFloat)width color:(UIColor *)color {
        self.borderWidth = width;
        self.borderColor = color;
    }
    
    #pragma mark - Kernel
    /**
     * @brief clip the cornerRadius with image, UIImageView must be setFrame before, no off-screen-rendered
     */
    - (void)zy_cornerRadiusWithImage:(UIImage *)image cornerRadius:(CGFloat)cornerRadius rectCornerType:(UIRectCorner)rectCornerType {
        CGSize size = self.bounds.size;
        CGFloat scale = [UIScreen mainScreen].scale;
        CGSize cornerRadii = CGSizeMake(cornerRadius, cornerRadius);
        
        UIGraphicsBeginImageContextWithOptions(size, NO, scale);
        if (nil == UIGraphicsGetCurrentContext()) {
            return;
        }
        UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:rectCornerType cornerRadii:cornerRadii];
        [cornerPath addClip];
        [image drawInRect:self.bounds];
        [self drawBorder:cornerPath];
        UIImage *processedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        objc_setAssociatedObject(processedImage, &kProcessedImage, @(1), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        self.image = processedImage;
    }
    
    /**
     * @brief clip the cornerRadius with image, draw the backgroundColor you want, UIImageView must be setFrame before, no off-screen-rendered, no Color Blended layers
     */
    - (void)zy_cornerRadiusWithImage:(UIImage *)image cornerRadius:(CGFloat)cornerRadius rectCornerType:(UIRectCorner)rectCornerType backgroundColor:(UIColor *)backgroundColor {
        CGSize size = self.bounds.size;
        CGFloat scale = [UIScreen mainScreen].scale;
        CGSize cornerRadii = CGSizeMake(cornerRadius, cornerRadius);
        
        UIGraphicsBeginImageContextWithOptions(size, YES, scale);
        if (nil == UIGraphicsGetCurrentContext()) {
            return;
        }
        UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:rectCornerType cornerRadii:cornerRadii];
        UIBezierPath *backgroundRect = [UIBezierPath bezierPathWithRect:self.bounds];
        [backgroundColor setFill];
        [backgroundRect fill];
        [cornerPath addClip];
        [image drawInRect:self.bounds];
        [self drawBorder:cornerPath];
        UIImage *processedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        objc_setAssociatedObject(processedImage, &kProcessedImage, @(1), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        self.image = processedImage;
    }
    
    /**
     * @brief set cornerRadius for UIImageView, no off-screen-rendered
     */
    - (void)zy_cornerRadiusAdvance:(CGFloat)cornerRadius rectCornerType:(UIRectCorner)rectCornerType {
        self.radius = cornerRadius;
        self.roundingCorners = rectCornerType;
        self.isRounding = NO;
        
        if (!self.hadAddObserver) {
            [[self class] swizzleMethod:NSSelectorFromString(@"dealloc") anotherMethod:@selector(zy_dealloc)];
            [self addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil];
            self.hadAddObserver = YES;
        }
    }
    
    /**
     * @brief become Rounding UIImageView, no off-screen-rendered
     */
    - (void)zy_cornerRadiusRoundingRect {
        self.isRounding = YES;
        
        if (!self.hadAddObserver) {
            [[self class] swizzleMethod:NSSelectorFromString(@"dealloc") anotherMethod:@selector(zy_dealloc)];
            [self addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil];
            self.hadAddObserver = YES;
        }
    }
    
    #pragma mark - Private
    - (void)drawBorder:(UIBezierPath *)path {
        if (0 != self.borderWidth && nil != self.borderColor) {
            [path setLineWidth:2 * self.borderWidth];
            [self.borderColor setStroke];
            [path stroke];
        }
    }
    
    - (void)zy_dealloc {
        if (self.hadAddObserver) {
            [self removeObserver:self forKeyPath:@"image"];
        }
        [self zy_dealloc];
    }
    
    - (void)validateFrame {
        if (self.frame.size.width == 0) {
            [self.class swizzleMethod:@selector(layoutSubviews) anotherMethod:@selector(zy_LayoutSubviews)];
        }
    }
    
    + (void)swizzleMethod:(SEL)oneSel anotherMethod:(SEL)anotherSel {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            Method oneMethod = class_getInstanceMethod(self, oneSel);
            Method anotherMethod = class_getInstanceMethod(self, anotherSel);
            
            method_exchangeImplementations(oneMethod, anotherMethod);
        });
    }
    
    - (void)zy_LayoutSubviews {
        [self zy_LayoutSubviews];
        if (self.isRounding) {
            [self zy_cornerRadiusWithImage:self.image cornerRadius:self.frame.size.width/2 rectCornerType:UIRectCornerAllCorners];
        } else if (0 != self.radius && 0 != self.roundingCorners && nil != self.image) {
            [self zy_cornerRadiusWithImage:self.image cornerRadius:self.radius rectCornerType:self.roundingCorners];
        }
    }
    
    #pragma mark - KVO for .image
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([keyPath isEqualToString:@"image"]) {
            UIImage *newImage = change[NSKeyValueChangeNewKey];
            if ([newImage isMemberOfClass:[NSNull class]]) {
                return;
            } else if ([objc_getAssociatedObject(newImage, &kProcessedImage) intValue] == 1) {
                return;
            }
            [self validateFrame];
            if (self.isRounding) {
                [self zy_cornerRadiusWithImage:newImage cornerRadius:self.frame.size.width/2 rectCornerType:UIRectCornerAllCorners];
            } else if (0 != self.radius && 0 != self.roundingCorners && nil != self.image) {
                [self zy_cornerRadiusWithImage:newImage cornerRadius:self.radius rectCornerType:self.roundingCorners];
            }
        }
    }
    
    #pragma mark property
    - (CGFloat)borderWidth {
        return [objc_getAssociatedObject(self, &kBorderWidth) floatValue];
    }
    
    - (void)setBorderWidth:(CGFloat)borderWidth {
        objc_setAssociatedObject(self, &kBorderWidth, @(borderWidth), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIColor *)borderColor {
        return objc_getAssociatedObject(self, &kBorderColor);
    }
    
    - (void)setBorderColor:(UIColor *)borderColor {
        objc_setAssociatedObject(self, &kBorderColor, borderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (BOOL)hadAddObserver {
        return [objc_getAssociatedObject(self, &kHadAddObserver) boolValue];
    }
    
    - (void)setHadAddObserver:(BOOL)hadAddObserver {
        objc_setAssociatedObject(self, &kHadAddObserver, @(hadAddObserver), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (BOOL)isRounding {
        return [objc_getAssociatedObject(self, &kIsRounding) boolValue];
    }
    
    - (void)setIsRounding:(BOOL)isRounding {
        objc_setAssociatedObject(self, &kIsRounding, @(isRounding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIRectCorner)roundingCorners {
        return [objc_getAssociatedObject(self, &kRoundingCorners) unsignedLongValue];
    }
    
    - (void)setRoundingCorners:(UIRectCorner)roundingCorners {
        objc_setAssociatedObject(self, &kRoundingCorners, @(roundingCorners), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (CGFloat)radius {
        return [objc_getAssociatedObject(self, &kRadius) floatValue];
    }
    
    - (void)setRadius:(CGFloat)radius {
        objc_setAssociatedObject(self, &kRadius, @(radius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }

     

  • 相关阅读:
    border-image
    实现页面变成灰色色调
    ie 浏览器“浏览器模式”和“文档模式”之间的区别
    vue-loader
    vue-cli创建的项目中使用sass
    v-html
    vue $forceUpdate 强制更新
    webpack-dev-server 不是内部命令
    vue devtools 以及热更新
    事件机制
  • 原文地址:https://www.cnblogs.com/X-Bin/p/5599403.html
Copyright © 2011-2022 走看看