Desenvolvimento iOS - a animação circular da barra de progresso do download inclui um exemplo de download usando AFN

Desenvolvimento iOS - a animação circular da barra de progresso do download inclui um exemplo de download usando AFN

Prefácio

No desenvolvimento do iOS, há muitos lugares onde você precisa usar uma barra de progresso para indicar o andamento do download.

Como mostrado

Insira a descrição da imagem aqui

Código

  • O primeiro é o pacote de animação em loop
  • ShowProgress.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ShowProgress : UIView

@property(nonatomic, assign) CGFloat progress;
@property(nonatomic, strong) UIColor *progressBarColor;

@end

NS_ASSUME_NONNULL_END
  • ShowProgress.m
#import "ShowProgress.h"

@implementation ShowProgress

- (instancetype)initWithFrame:(CGRect)frame {
    
    
    if (self = [super initWithFrame:frame]) {
    
    
        self.backgroundColor = [UIColor clearColor];
        self.progressBarColor = [UIColor blackColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGFloat xCenter = rect.size.width * 0.5;
    CGFloat yCenter = rect.size.height * 0.5;
    
    [_progressBarColor set];
    
    //设置圆环的宽度
    CGContextSetLineWidth(ctx, 2); //1.5 圆环的宽度
    CGContextSetLineCap(ctx, kCGLineCapRound);
    CGFloat to = - M_PI * 0.5 + self.progress * M_PI * 2; // 初始值0.05
    //半径
    CGFloat radius = rect.size.width * 0.5 - 1;
    CGContextAddArc(ctx, xCenter, yCenter, radius, - M_PI * 0.5, to, 0);
    CGContextStrokePath(ctx);
}

- (void)setProgress:(CGFloat)progress {
    
    
    _progress = progress;
    if (_progress >= 1) {
    
    
        [self removeFromSuperview];
    } else {
    
    
        [self setNeedsDisplay];
    }
}

@end

usar

  • Geralmente use AFN para baixar
#pragma mark - AFN 下载

- (void)downLoadUrl:(NSString *)urlString
      progressBlock:(DownProgressBlock _Nullable)progressBlock
   downSuccessBlock:(DownSuccessBlock _Nullable)downSuccessBlock
    downFailedBlock:(DownFailedBlock _Nullable)downFailedBlock {
    
    
    AFHTTPSessionManager *manager = [self manager];
    //2.1 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    __weak typeof(self) weakSelf = self;
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress) {
    
     //进度
        CGFloat rate = (100.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
        [weakSelf _getMainThread:^{
    
    
            if (progressBlock) {
    
    
                progressBlock(rate);
            }
        }];
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    
    
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        //response.suggestedFilename后缀名 xxx.mp4
        //https://dl.anycdn.cc/data/static/ay/bao.zip
        NSString *fullpath = [caches stringByAppendingPathComponent:response.suggestedFilename];
        NSURL *filePathUrl = [NSURL fileURLWithPath:fullpath];

        return filePathUrl;
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    
     //都在主线程
        if (error) {
    
     //加载失败
            downFailedBlock(error);
        }

        NSString *file = [[filePath absoluteString] stringByReplacingOccurrencesOfString:@"file://" withString:@""];
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        if(filePath) {
    
     //加载成功返回路径
            downSuccessBlock(file, caches);
        }
    }];

    //3.启动任务
    [downloadTask resume];
}

- (AFHTTPSessionManager *)manager {
    
    
    static AFHTTPSessionManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    
    
        if (manager == nil) {
    
    
            manager = [AFHTTPSessionManager manager];
            manager.requestSerializer.timeoutInterval = kTimeoutInterval;
        }
    });
    return manager;
}

#pragma mark - AFN 下载 end
  • Preencha ViewController.m com o progresso da animação circular por meio de um cronômetro
#import "ViewController.h"
#import "ShowProgress.h"

static NSInteger const kMaxTime = 10;
@interface ViewController ()

@property(nonatomic, strong) UIView *backView;
@property(nonatomic, strong) ShowProgress *_Nullable progressView; //下载进度页面
@property(nonatomic, strong) NSTimer *timer;
@property(nonatomic, assign) NSInteger count;

@end

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    
    [self startTask];
}

- (void)viewDidLoad {
    
    
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:self.backView];
}

- (UIView *)backView {
    
    
    if(_backView == nil) {
    
    
        _backView = [[UIView alloc]initWithFrame:CGRectMake((self.view.frame.size.width - 100) / 2, (self.view.frame.size.height - 100) / 2, 100, 100)];
        _backView.backgroundColor = [UIColor clearColor];
        _backView.layer.borderColor = [UIColor whiteColor].CGColor;
        _backView.layer.borderWidth = 2;
        _backView.layer.cornerRadius = self.backView.frame.size.width / 2;
        _backView.clipsToBounds = YES;
        _backView.hidden = YES;
    }
    return _backView;
}

- (ShowProgress *)progressView {
    
    
    if(_progressView == nil) {
    
    
        _progressView = [[ShowProgress alloc]initWithFrame:CGRectMake((self.view.frame.size.width - 100) / 2, (self.view.frame.size.height - 100) / 2, 100, 100)];
    }
    return _progressView;
}

- (void)startTask {
    
     //开始
    self.backView.hidden = NO;
    [self.view addSubview:self.progressView];
    
    _timer = [NSTimer scheduledTimerWithTimeInterval:kMaxTime target:self selector:@selector(taskAction) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
}

- (void)endTask {
    
     //结束
    [_timer invalidate];
    _timer = nil;
    self.progressView = nil;
    [self.progressView removeFromSuperview];
}

- (void)taskAction {
    
    
    if(_count == kMaxTime) {
    
    
        [self endTask];
    }
    [self.progressView setProgress:_count * 0.1];
    _count ++;
}

@end
  • Use o método setProgress: de self.progressView para preencher o andamento do download retornado pelo AFN em associação com a animação existente

Acho que você gosta

Origin blog.csdn.net/weixin_41732253/article/details/110222129
Recomendado
Clasificación