为ImageView添加渐变效果<无侵入式>

话不多说,开篇立言
为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];
        }

    }];

}

这个方法只适用于小范围的添加动画效果,如果需要全局统一的添加动画效果则需要采取下面的方式。

  • SDWebImage新版本在UIView+webCache的分类中提供了一个sd_imageTransition的关联对象,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;

这个关联对象在下述方法中被引用

- (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 *)context;

而sd_setImage的方法最终都会访问这个方法。
如果我们项目需要为全部的网络图片加上渐变动画的话,只需要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 *)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];
    
}

在该方法调用前,统一为view赋值sd_imageTransition,即可实现为imageView统一添加渐变效果,而不用更改项目的一行代码。

另外 [SDWebImageTransition fadeTransition] 只是工厂方法的一种,还有其他很多的动画效果可以使用。

你可能感兴趣的:(为ImageView添加渐变效果<无侵入式>)