美文网首页
加载网络图片圆形进度条(利用SDWebImage)

加载网络图片圆形进度条(利用SDWebImage)

作者: Mr_ZNN | 来源:发表于2019-09-28 15:40 被阅读0次

    背景:

    最近项目需要加载网络图片的时候显示圆形进度,提高用户体验,研究了一下做个记录。


    progrss.png

    思路

    实现起来其实很简单。
    1、创建UIImageView的分类,设置时直接调用分类方法。
    2、借助SDWebImage的方法,拿到加载进度。

    - (void)sd_setImageWithURL:(nullable NSURL *)url
              placeholderImage:(nullable UIImage *)placeholder
                       options:(SDWebImageOptions)options
                      progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                     completed:(nullable SDExternalCompletionBlock)completedBlock;
    

    3、自定义进度视图,绘制进度。

    源码

    UIImageView分类

    #import "UIImageView+WebCache.h"
    #import <SDWebImage/UIImageView+WebCache.h>
    #import "CustomProgressView.h"
    
    @interface UIImageView (ProgressView)
    
    - (void)sd_setImageWithURL:(NSURL *)url usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView;
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView;
    
    - (void)removeProgressView;
    
    @end
    
    #import "UIImageView+ProgressView.h"
    
    
    #define TAG_PROGRESS_VIEW 149462
    
    @implementation UIImageView (ProgressView)
    
    - (void)addProgressView:(CustomProgressView *)progressView {
        CustomProgressView *existingProgressView = (CustomProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW];
        if (!existingProgressView) {
            if (!progressView) {
                progressView = [[CustomProgressView alloc] initWithFrame:self.frame];
                progressView.backgroundColor = [UIColor grayColor];
            }
    
            progressView.tag = TAG_PROGRESS_VIEW;
            progressView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
    
            float width = progressView.frame.size.width;
            float height = progressView.frame.size.height;
            float x = (self.frame.size.width / 2.0) - width/2;
            float y = (self.frame.size.height / 2.0) - height/2;
            progressView.frame = CGRectMake(x, y, width, height);
    
            [self addSubview:progressView];
        }
    }
    
    - (void)updateProgress:(CGFloat)progress {
        CustomProgressView *progressView = (CustomProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW];
        if (progressView) {
            progressView.progressValue = progress;
        }
    }
    
    - (void)removeProgressView {
        CustomProgressView *progressView = (CustomProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW];
        if (progressView) {
            [progressView removeFromSuperview];
        }
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url usingProgressView:(CustomProgressView *)progressView {
        [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingProgressView:(CustomProgressView *)progressView {
        [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingProgressView:(CustomProgressView *)progressView{
        [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView {
        [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView {
        [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView {
        [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock usingProgressView:progressView];
    }
    
    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock usingProgressView:(CustomProgressView *)progressView {
        [self addProgressView:progressView];
        
        __weak typeof(self) weakSelf = self;
    
        [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
            
            CGFloat progress = ((CGFloat)receivedSize / (CGFloat)expectedSize);
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf updateProgress:progress];
            });
            
            if (progressBlock) {
                progressBlock(receivedSize, expectedSize, url);
            }
            
        } completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
            
            [weakSelf removeProgressView];
            if (completedBlock) {
                completedBlock(image, error, cacheType, imageURL);
            }
            
        }];
        
    }
    
    @end
    

    进度条视图

    #import <UIKit/UIKit.h>
    
    @interface CustomProgressView : UIView
    
    @property (nonatomic, assign) CGFloat progressValue;
    
    @end
    
    #import "CustomProgressView.h"
    
    @interface CustomProgressView ()
    
    @property (nonatomic, strong) UILabel* progressLabel;
    
    @end
    @implementation CustomProgressView
    
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            
        }
        return self;
    }
    -(UILabel *)progressLabel {
        if (!_progressLabel) {
            _progressLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
            [self addSubview:_progressLabel];
        }
        return _progressLabel;
    }
    
    -(void)layoutSubviews {
        self.progressLabel.center = self.center;
    }
    
    - (void)setProgressValue:(CGFloat)progressValue
    {
        _progressValue = progressValue;
        
        // 设置label的文字
        self.progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progressValue * 100];
        NSLog(@"self.progressLabel - %f",progressValue);
        
        // 重绘
        [self setNeedsDisplay];
    }
    
    -(void)drawRect:(CGRect)rect {
        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:self.frame.size.width < self.frame.size.height ? self.frame.size.width * 0.3 : self.frame.size.height * 0.3 startAngle:-M_PI_2 endAngle:2 * M_PI * self.progressValue - M_PI_2 clockwise:1];
        
        [path setLineWidth:5];
        [[UIColor orangeColor] setStroke];
        // 填充
        [path stroke];
    }
    
    @end
    

    调用方法

    [self.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://static1.beesns.cn/user/avatar/20190812/568deb487b8f5575b19a056e501d7533.jpg"] placeholderImage:nil options:SDWebImageCacheMemoryOnly usingProgressView:nil];
    

    补充

    画进度的时候根据进度绘制,调用[self setNeedsDisplay];会自动调用
    -(void)drawRect:(CGRect)rect;

    相关文章

      网友评论

          本文标题:加载网络图片圆形进度条(利用SDWebImage)

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