iOS中使用NSProgress类来创建UI进度条的方法详解

2020-01-15 16:14:24王振洲

一、引言

在iOS7之前,系统一直没有提供一个完整的框架来描述任务进度相关的功能。这使得在开发中进行耗时任务进度的监听将什么麻烦,在iOS7之后,系统提供了NSProgress类来专门报告任务进度。


二、创建单任务进度监听器

单任务进度的监听是NSProgress最简单的一种运用场景,我们来用定时器模拟一个耗时任务,示例代码如下:


@interface ViewController ()
{
 NSProgress * progress;
}
@end

@implementation ViewController

- (void)viewDidLoad {
 [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
 //这个方法将创建任务进度管理对象 UnitCount是一个基于UI上的完整任务的单元数
 progress = [NSProgress progressWithTotalUnitCount:10];
 NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(task) userInfo:nil repeats:YES];
 //对任务进度对象的完成比例进行监听
 [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{
 NSLog(@"进度= %f",progress.fractionCompleted);
}
-(void)task{
 //完成任务单元数+1
 
 if (progress.completedUnitCount<progress.totalUnitCount) {
  progress.completedUnitCount +=1;
 }
 
}

上面的示例代码中,fractionCompleted属性为0-1之间的浮点值,为任务的完成比例。NSProgress对象中还有两个字符串类型的属性,这两个属性将进度信息转化成固定的格式:


//显示完后比例 如:10% completed
@property (null_resettable, copy) NSString *localizedDescription;
//完成数量 如:1 of 10
@property (null_resettable, copy) NSString *localizedAdditionalDescription;

 

三、创建多任务进度监听器

上面演示了只有一个任务时的进度监听方法,实际上,在开发中,一个任务中往往又有许多子任务,NSProgress是以树状的结构进行设计的,其支持子任务的嵌套,示例如下:


- (void)viewDidLoad {
 [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
 //这个方法将创建任务进度管理对象 UnitCount是一个基于UI上的完整任务的单元数
 progress = [NSProgress progressWithTotalUnitCount:10];
 //对任务进度对象的完成比例进行监听
 [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];
 //向下分支出一个子任务 子任务进度总数为5个单元 即当子任务完成时 父progerss对象进度走5个单元
 [progress becomeCurrentWithPendingUnitCount:5];
 [self subTaskOne];
 [progress resignCurrent];
 //向下分出第2个子任务
 [progress becomeCurrentWithPendingUnitCount:5];
 [self subTaskOne];
 [progress resignCurrent];
}

-(void)subTaskOne{
 //子任务总共有10个单元
 NSProgress * sub =[NSProgress progressWithTotalUnitCount:10];
 int i=0;
 while (i<10) {
  i++;
  sub.completedUnitCount++;
 }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{
 NSLog(@"= %@",progress.localizedAdditionalDescription);
}