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
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