美文网首页iOS学习程序员iOS开发
7.通过SDWebImage实现图片加载时的渐变效果

7.通过SDWebImage实现图片加载时的渐变效果

作者: Lee丶Way | 来源:发表于2017-03-10 18:33 被阅读745次

    回头望,伴你走,从来未曾幸福过
    恨太多,没结果,往事重提是折磨

    先上效果图:
    这些图片是在我限制了网速的情况下加载的:


    实现效果

    思路解析

    想到渐变属性的时候,自然而然的想起CATransition这个类
    先看整体的实现代码:

    首先找到UIImageView+WebCache.m这个文件中的- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock这个函数(大约在44行处)

    修改成这个样子

    - (void)sd_setImageWithURL:(NSURL *)url 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 = placeholder;
            });
        }
        
        if (url) {
    
            // check if activityView is enabled or not
            if ([self showActivityIndicatorView]) {
                [self addActivityIndicator];
            }
    
            __weak __typeof(self)wself = self;
            id <SDWebImageOperation> 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(image, error, cacheType, url);
                        return;
                    }
                    else if (image) {
                        CATransition *animation = [CATransition animation];
                        animation.duration = .85f;
                        animation.type = kCATransitionFade;
                        animation.removedOnCompletion = YES;
                        [wself.layer addAnimation:animation forKey:@"transition"];
                        wself.image = image;
                        [wself setNeedsLayout];
                    } else {
                        if ((options & SDWebImageDelayPlaceholder)) {
                            wself.image = placeholder;
                            [wself setNeedsLayout];
                        }
                    }
                    if (completedBlock && finished) {
                        completedBlock(image, error, cacheType, url);
                    }
                });
            }];
            [self.layer removeAnimationForKey:@"transition"];
            [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);
                }
            });
        }
    }
    

    在大约72行处添加

                        CATransition *animation = [CATransition animation];
                        animation.duration = .85f;
                        animation.type = kCATransitionFade;
                        animation.removedOnCompletion = YES;
                        [wself.layer addAnimation:animation forKey:@"transition"];
    

    不需要过多解释kCATransitionFade意思是 交叉淡化过渡
    这个 type 还有几个兄弟:

    kCATransitionFade              //交叉淡化过渡                     
    kCATransitionMoveIn            //移动覆盖原图                     
    kCATransitionPush              //新视图将旧视图推出去                     
    kCATransitionReveal            //底部显出来 
    

    因为我们的需求是渐变嘛,所以就使用kCATransitionFade

    <small>注意啦</small>
    一定要在下载图片的这个Block结束后,把animation去掉[self.layer removeAnimationForKey:@"transition"];
    为什么呢,如果你不去掉,在cell复用的时候,会出现加载重复的情况呢。/坏笑 不信的话,你别加呀。

    好心一早放开我,从头努力也坎坷,通通不要好过
    为何唱着这首歌,为怨恨而分手,问你是否原谅我

    相关文章

      网友评论

      • ShevaKuilin:其实CATransition动画直接卸载sd下载完成后的completed中就可以了,至于remove这个动画,只需要遵循CAAnimationDelegate,然后实现func animationDidStop(_ anim: CAAnimation, finished flag: Bool)方法,在该方法中判断CATransition动画事件是否已完成,完成后删除即可,不需要改动源码
      • 蛮荒星域:SDWebimage是cocoapods引入的,所以不想直接改动代码,有没有其他的方式加入这段动画呢?
        Lee丶Way:@ShevaKuilin :+1:
        ShevaKuilin:我有更简单的方法,不用改源码
        Lee丶Way:写一个类继承过来怎么样
      • 82b3228ad0f7:厉害了
      • 否极泰来_L:歌词很强势,可以的
        Lee丶Way:@航磊_ :grin:

      本文标题:7.通过SDWebImage实现图片加载时的渐变效果

      本文链接:https://www.haomeiwen.com/subject/ucdogttx.html