話不多說,開篇立言
為imageView添加漸變動畫有很多方法
- 比如新增分類,重寫方法
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
__weak typeof(self) weakSelf = self;
[self sd_setImageWithURL:url placeholderImage:placeholder completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// cacheType == SDImageCacheTypeNone 意味著首次加載
if (image && cacheType == SDImageCacheTypeNone) {
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[weakSelf.layer addAnimation:transition forKey:nil];
}
}];
}
這個方法只適用于小范圍的添加動畫效果,如果需要全局統(tǒng)一的添加動畫效果則需要采取下面的方式。
- SDWebImage新版本在UIView+webCache的分類中提供了一個sd_imageTransition的關聯(lián)對象,SDWebImageTransition是只是對CATransition的進一步封裝,詳細可以訪問SDWebImage訪問
/**
The image transition when image load finished. See `SDWebImageTransition`.
If you specify nil, do not do transition. Defautls to nil.
*/
@property (nonatomic, strong, nullable) SDWebImageTransition *sd_imageTransition;
這個關聯(lián)對象在下述方法中被引用
- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
placeholderImage:(nullable UIImage *)placeholder
options:(SDWebImageOptions)options
operationKey:(nullable NSString *)operationKey
setImageBlock:(nullable SDSetImageBlock)setImageBlock
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary<NSString *, id> *)context;
而sd_setImage的方法最終都會訪問這個方法。
如果我們項目需要為全部的網(wǎng)絡圖片加上漸變動畫的話,只需要hook這個方法即可
+ (void)load {
[self swizzleInstanceMethod:@selector(sd_internalSetImageWithURL:placeholderImage:options:operationKey:setImageBlock:progress:completed:context:)];
}
+ (void)swizzleInstanceMethod:(SEL)sel {
SEL other = NSSelectorFromString([NSString stringWithFormat:@"gp_%@",NSStringFromSelector(sel)]);
Method org = class_getInstanceMethod(self, sel);
Method method = class_getInstanceMethod(self, other);
if (class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method))) {
class_replaceMethod(self, other, method_getImplementation(org), method_getTypeEncoding(org));
} else {
method_exchangeImplementations(org, method);
}
}
-(void)gp_sd_internalSetImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options operationKey:(NSString *)operationKey setImageBlock:(SDSetImageBlock)setImageBlock progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock context:(NSDictionary<NSString *,id> *)context {
if (!self.sd_imageTransition) {
self.sd_imageTransition = [SDWebImageTransition fadeTransition];
self.animationDuration = 0.3;
}
[self gp_sd_internalSetImageWithURL:url placeholderImage:placeholder options:options operationKey:operationKey setImageBlock:setImageBlock progress:progressBlock completed:completedBlock context:context];
}
在該方法調用前,統(tǒng)一為view賦值sd_imageTransition,即可實現(xiàn)為imageView統(tǒng)一添加漸變效果,而不用更改項目的一行代碼。
另外 [SDWebImageTransition fadeTransition] 只是工廠方法的一種,還有其他很多的動畫效果可以使用。