iOS UIView异步绘制实现圆角的方案

前言

  1. 关于离屏渲染、圆角卡顿,网络上已经有大量理论性的文章。如果有兴趣推荐看YYKit作者的相关文章。
  2. 包括我在内,大部分人看了理论文章后,可能还是一知半解。想要看具体实现,能找到的都是YYKit、ASDK这种重量型的框架,顿感头大。萌新只是简单想优化一下圆角卡顿而已 o(╥﹏╥)o
  3. 本文是我看完一系列文章后,自己给出的项目中可直接用的圆角优化方案。

正文

核心思路:

  1. iOS9以后,UIImageView的圆角已经不需要我们操心了
  2. 之前很多人可能就已经知道,最简单粗暴的办法就是让UI切一张图盖在上面。但这样不同的圆角尺寸无法复用。本方案就是沿着这个思路自己画一张这样的图。
  3. 仅适用于背景色为纯色的场景

代码实现:

//
//  UIView+ZHRadius.m
//  ZHDemos
//
//  Created by xuzhenhao on 2018/7/11.
//  Copyright © 2018年 xuzhenhao. All rights reserved.
//

#import "UIView+ZHRadius.h"

@implementation UIView (ZHRadius)

#pragma mark - public method
- (void)zh_addRadius:(CGFloat)radius
             corners:(UIRectCorner)corners
             bgColor:(UIColor *)bgColor{
    UIImageView *imgView = [self _addCornerImageView];
    CGRect bounds = self.bounds;
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self _addCornerRadius:radius corners:corners imageView:imgView bounds:bounds bgColor:bgColor];
    });
}
#pragma mark - private method
- (UIImageView *)_addCornerImageView{
    UIImageView *imageView = nil;
    for (UIView *subView in self.subviews) {
        if (subView.tag == 1234567) {
            imageView = (UIImageView *)subView;
            break;
        }
    }
    if (!imageView) {
        imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        imageView.userInteractionEnabled = NO;
        imageView.opaque = YES;
        imageView.tag = 1234567;//防重复添加
        //置顶
        imageView.layer.zPosition = 999;
        [self addSubview:imageView];
        [self bringSubviewToFront:imageView];
    }
    
    return imageView;
}
- (void)_addCornerRadius:(CGFloat)radius corners:(UIRectCorner)corners imageView:(UIImageView *)imageView bounds:(CGRect)bounds bgColor:(UIColor *)bgColor{
    
    UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:bounds];
    UIBezierPath *cornerPath = [[UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)] bezierPathByReversingPath];
    
    [path appendPath:cornerPath];
    //裁剪出圆角路径
    CGContextAddPath(context, path.CGPath);
    //用背景色填充路径
    [bgColor set];
    CGContextFillPath(context);
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    dispatch_async(dispatch_get_main_queue(), ^{
        imageView.image = image;
    });
}

@end

复制代码

你可能感兴趣的:(iOS UIView异步绘制实现圆角的方案)