美文网首页
iOS 圆角&离屏渲染

iOS 圆角&离屏渲染

作者: yyggzc521 | 来源:发表于2021-09-11 09:21 被阅读0次

    离屏渲染的原因是什么?可以自行搜索一下“画家算法”

    UIImageView
    1. 以下情况不会离屏渲染
      设置image + masksToBounds
        imageBackView.image = [UIImage imageNamed:@"photoOne"];
        imageBackView.layer.cornerRadius = 50;
        imageBackView.layer.masksToBounds = YES;
       // imageBackView.clipsToBounds = YES;
    
    1. 下面会离屏渲染
      背景色 + image + 圆角 + masksToBounds(有背景色或边框就触发,没有不会)
      解决方法
      使用Core Graphics + UIBezierPath绘制图片圆角
    UIButton

    clipsToBounds + image(有image触发,没有不会)

    1. 以下情况不会离屏渲染
      只设置圆角和背景色

    2. 下面会离屏渲染
      设置圆角+image(或背景image)

        UIButton *controlButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 150, controlView.bounds.size.width, 40)];
        controlButton.backgroundColor = [UIColor blueColor];
        [controlButton setTitle:@"会离屏渲染" forState:UIControlStateNormal];
        [controlButton setImage:[UIImage imageNamed:@"LayerBtnImg"] forState:UIControlStateNormal];
        controlButton.layer.cornerRadius = 20;
        controlButton.layer.masksToBounds = YES;
        [controlView addSubview:controlButton];
    
    • btn设置图片和圆角,打开clipsToBounds = YES,触发了离屏渲染,
    • btn设置背景颜色和圆角,打开clipsToBounds = YES,没有触发离屏渲染
    • img设置图片和圆角、背景色,打开masksToBounds = YES,触发了离屏渲染
    • img设置背景颜色和圆角,打开masksToBounds = YES,没有触发离屏渲染

    结论:只是控件设置了圆角或(圆角+裁剪)并不会触发离屏渲染,同时要满足父layer需要裁剪时,子layer也因为父layer设置了圆角也需要被裁剪(即视图contents有内容并发生了多图层被裁剪)时才会触发离屏渲染

    UIView

    未完,待更新

    UILabel

    YYKit是开发中经常用的三方库,YYImage对图片圆角的处理方法是值得推荐的

    - (UIImage *)imageByRoundCornerRadius:(CGFloat)radius
                                  corners:(UIRectCorner)corners
                              borderWidth:(CGFloat)borderWidth
                              borderColor:(UIColor *)borderColor
                           borderLineJoin:(CGLineJoin)borderLineJoin {
        
        if (corners != UIRectCornerAllCorners) {
            UIRectCorner tmp = 0;
            if (corners & UIRectCornerTopLeft) tmp |= UIRectCornerBottomLeft;
            if (corners & UIRectCornerTopRight) tmp |= UIRectCornerBottomRight;
            if (corners & UIRectCornerBottomLeft) tmp |= UIRectCornerTopLeft;
            if (corners & UIRectCornerBottomRight) tmp |= UIRectCornerTopRight;
            corners = tmp;
        }
        
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGContextScaleCTM(context, 1, -1);
        CGContextTranslateCTM(context, 0, -rect.size.height);
        
        CGFloat minSize = MIN(self.size.width, self.size.height);
        if (borderWidth < minSize / 2) {
            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(radius, borderWidth)];
            [path closePath];
            
            CGContextSaveGState(context);
            [path addClip];
            CGContextDrawImage(context, rect, self.CGImage);
            CGContextRestoreGState(context);
        }
        
        if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) {
            CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale;
            CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset);
            CGFloat strokeRadius = radius > self.scale / 2 ? radius - self.scale / 2 : 0;
            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, borderWidth)];
            [path closePath];
            
            path.lineWidth = borderWidth;
            path.lineJoinStyle = borderLineJoin;
            [borderColor setStroke];
            [path stroke];
        }
        
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    

    如何检测离屏渲染?

    1. 模拟器 debug-选中 color Offscreen - Renderd 离屏渲染的图层高亮成黄 可能存在性能问题
    2. 真机 Instrument-选中 Core Animation-勾选 Color Offscreen-Rendered Yellow
    3. Core Animation工具检测离屏渲染
      对离屏渲染的检测,苹果为我们提供了一个测试工具Core Animation。可以在Xcode->Open Develeper Tools->Instruments中找到

    参考资料:
    iOS 离屏渲染探究
    常用组件高效切圆角方法

    https://www.jianshu.com/p/af65510eebd6
    iOS 真实的离屏渲染

    相关文章

      网友评论

          本文标题:iOS 圆角&离屏渲染

          本文链接:https://www.haomeiwen.com/subject/rqugwltx.html