iOS切圆角方法解决离屏渲染问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS切圆角方法解决离屏渲染问题相关的知识,希望对你有一定的参考价值。
参考技术A 1、UIView切圆角UIView在切圆角的时候使用
会导致离屏渲染。
解决办法:不能使用masksToBounds,view.clipsToBounds;直接切圆角:
这是方法适用于切全圆角,如果是切指定圆角的时候就不行了;
增加切指定圆角的方法
使用改方法满足了切指定圆角的需求;但是又会导致离屏渲染问题;
这儿想到一个办法就是使用UIImageView替换UIView;或者是在底层插入UIImageView;
首先要设置一个UIImage根据背景设置
方法实现
之后再,具体实现见下面UIImageView切圆角方法;
2、UIView增加阴影效果:
会导致离屏渲染。
解决办法:设置阴影路径可避免离屏渲染
实现上述方法就可以实现圆角+阴影效果
3、UIImageView切圆角
简便的方法
在ios9.0之后加载png图片设置圆角不会导致离屏渲染;
但是如果在给UIImageView增加一个背景色就会导致离屏渲染;
最优的解决办法:通过给UIImageView加载的图片切圆角;
给图片切圆角之后重新赋值给UIImageView;如下
需要给定size时,如果使用的Masnory添加的预约,则需要立即更新之后才会生效
将持续优化方法,找到最适合的方法
解决圆角离屏渲染方案
最近看了大量的优化tableview方案,为了配合sd下载图片,并且解决圆角图片离屏渲染问题,于是利用category自己写了个处理圆角的方法,解决了离屏渲染问题(并不是非常高效,感觉只是降低了GPU的消耗,但是提升了CPU的消耗,但是好歹也算是能提高一点fps),我还是更推荐使用yyimage下载图片,里面封装了处理圆角图片方法。
下面是代码:
// // UIImageView+CornerRadius.m // test // // Created by gkoudai_xsm on 16/4/11. // Copyright © 2016年 gkoudai_xsm. All rights reserved. // #import <objc/runtime.h> #import "UIImageView+CornerRadius.h" static NSString * const kIsRounding = @"kIsRounding"; static NSString * const kHadAddObserver = @"kHadAddObserver"; static NSString * const kProcessedImage = @"kProcessedImage"; @interface UIImageView () //在category里添加属性 自己实现get和set方法 objc_getAssociatedObject/objc_setAssociatedObject @property (nonatomic ,assign)BOOL isRounding; @property (nonatomic ,assign)BOOL hadAddObserver; @end @implementation UIImageView (CornerRadius) //public method - (instancetype)initWithRoundingRectImageView{ self = [super init]; if (self) { [self roundingRect]; } return self; } - (void) roundingRect { self.isRounding = YES; if (!self.hadAddObserver) { //添加个kvo [self addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil]; self.hadAddObserver = YES; } } #pragma mark - KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)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; } if (self.isRounding) { [self roundingRectWithImage:newImage cornerRadius:self.frame.size.width/2]; } } } #pragma mark - 处理图片 - (void)roundingRectWithImage:(UIImage *)image cornerRadius:(CGFloat)cornerRadius { CGSize size = self.bounds.size; CGFloat scale = [UIScreen mainScreen].scale; CGSize cornerRadii = CGSizeMake(cornerRadius, cornerRadius); // //获得用来处理图片的图形上下文,设置no为不透明 UIGraphicsBeginImageContextWithOptions(size, NO, scale); if (nil == UIGraphicsGetCurrentContext()) { return; } //针对某个角画圆形区域 UIBezierPath *roundingPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:cornerRadii]; // 添加裁剪 [roundingPath addClip]; // 边框线宽 roundingPath.lineWidth = 0.1; [image drawInRect:self.bounds]; // 开始画 [roundingPath stroke]; //从当前上下文中获取一个UIImage对象 UIImage *processedImage = UIGraphicsGetImageFromCurrentImageContext(); //关闭图形上下文 UIGraphicsEndImageContext(); //关联一个处理的图片 objc_setAssociatedObject(processedImage, &kProcessedImage, @(1), OBJC_ASSOCIATION_RETAIN_NONATOMIC); self.image = processedImage; } #pragma mark - Property - (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); } #pragma mark - dealloc - (void)dealloc{ if (self.hadAddObserver) { [self removeObserver:self forKeyPath:@"image"]; } } @end
以上是关于iOS切圆角方法解决离屏渲染问题的主要内容,如果未能解决你的问题,请参考以下文章