解决圆角离屏渲染方案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决圆角离屏渲染方案相关的知识,希望对你有一定的参考价值。
最近看了大量的优化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
以上是关于解决圆角离屏渲染方案的主要内容,如果未能解决你的问题,请参考以下文章