关于离屏渲染,参考这篇,说的不要太详细:http://ios.xueliedu.com/a/iospx/2016/0605/22671_5.html
因为现在app圆角的东西已经太多了,为了60帧的信仰,配合SDWebImage做了些修改,实际上是先将image处理后再做的缓存。所以当url相同的时候去缓存池读出来的图片是先做过剪裁的,也有其相应的弊端。
//剪裁方法
- (UIImage *)imageWithRoundCorner:(UIImage *)sourceImage cornerRadius:(CGFloat)cornerRadius size:(CGSize)size{
CGFloat scale = [UIScreen mainScreen].scale;
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
CGRect bounds = CGRectMake(0, 0, size.width, size.height);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:cornerRadius];
[path addClip];
[sourceImage drawInRect:bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
//添加在UIImageView+WebCache
- (void)sd_setRoundImageWithURL:(NSURL *)url cornerRadius:(CGFloat)cornerRadius placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
dispatch_main_async_safe(^{
self.image = [self imageWithRoundCorner:placeholder cornerRadius:cornerRadius size:placeholder.size];
});
}
if (url) {
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self;
id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock( [self imageWithRoundCorner:image cornerRadius:cornerRadius size:placeholder.size], error, cacheType, url);
return;
}
else if (image) {
wself.image = [self imageWithRoundCorner:image cornerRadius:cornerRadius size:placeholder.size];
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = [self imageWithRoundCorner:placeholder cornerRadius:cornerRadius size:placeholder.size];
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
//这时候读的是缓存里的,无需再剪裁
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[self removeActivityIndicator];
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
//添加在UIButton+WebCache
- (void)sd_setRoundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self setImage:[self imageWithRoundCorner:placeholder cornerRadius:placeholder.size.width size:placeholder.size] forState:state];
[self sd_cancelImageLoadForState:state];
if (!url) {
[self.imageURLStorage removeObjectForKey:@(state)];
dispatch_main_async_safe(^{
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
return;
}
self.imageURLStorage[@(state)] = url;
__weak __typeof(self)wself = self;
id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe(^{
__strong UIButton *sself = wself;
if (!sself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock([self imageWithRoundCorner:placeholder cornerRadius:placeholder.size.width size:placeholder.size], error, cacheType, url);
return;
}
else if (image) {
[sself setImage:[self imageWithRoundCorner:placeholder cornerRadius:placeholder.size.width size:placeholder.size] forState:state];
}
if (completedBlock && finished) {
completedBlock([self imageWithRoundCorner:placeholder cornerRadius:placeholder.size.width size:placeholder.size], error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forState:state];
}