亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS中使用NSProgress類來創建UI進度條的方法詳解

2020-07-26 03:19:35
字體:
來源:轉載
供稿:網友

一、引言

在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);}

NSProgress的這種樹狀設計模式乍看起來確實有些令人費解,有一點需要注意,becomeCurrentWithPendingUnitCount:方法的意義是將此NSProgress對象注冊為當前線程任務的根進度管理對象,resignCurrent方法為取消注冊,這兩個方法必須成對出現,當一個NSProgress對象被注冊為當前線程的根節點時,后面使用類方法 progressWithTotalUnitCount:創建的NSProgress對象都默認作為子節點添加。

四、iOS9之后進行多任務進度監聽的新設計方法

        正如上面的例子所演示,注冊根節點的方式可讀性很差,代碼結構也不太清晰,可能Apple的工程師們也覺得如此,在iOS9之后,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]; //創建子節點 NSProgress * sub = [NSProgress progressWithTotalUnitCount:10 parent:progress pendingUnitCount:5]; NSProgress * sub2 = [NSProgress progressWithTotalUnitCount:10 parent:progress pendingUnitCount:5]; for (int i=0; i<10; i++) {  sub.completedUnitCount ++;  sub2.completedUnitCount ++; }}

如上面代碼所示,代碼結構變得更加清晰,可操作性也更強了。

五、一點小總結

//獲取當前線程的進度管理對象根節點//注意:當有NSProgress對象調用了becomeCurrentWithPendingUnitCount:方法后,這個方法才能獲取到+ (nullable NSProgress *)currentProgress;//創建一個NSProgress對象,需要傳入進度的單元數量+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount;//和上一個方法功能相似 iOS9之后的新方法+ (NSProgress *)discreteProgressWithTotalUnitCount:(int64_t)unitCount;//iOS9之后的新方法 創建某個進度指示器節點的子節點+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount parent:(NSProgress *)parent pendingUnitCount:(int64_t)portionOfParentTotalUnitCount;//NSProgress實例的初始化方法 自父節點參數可以為nil- (instancetype)initWithParent:(nullable NSProgress *)parentProgressOrNil userInfo:(nullable NSDictionary *)userInfoOrNil;//注冊為當前線程根節點- (void)becomeCurrentWithPendingUnitCount:(int64_t)unitCount;//取消注冊 與注冊方法必須同步出現- (void)resignCurrent;//iOS9新方法 向一個節點中添加一個子節點- (void)addChild:(NSProgress *)child withPendingUnitCount:(int64_t)inUnitCount;//進度單元總數@property int64_t totalUnitCount;//已完成的進度單元數@property int64_t completedUnitCount;//是否可取消@property (getter=isCancellable) BOOL cancellable;//是否可暫停@property (getter=isPausable) BOOL pausable;//進度比例 0-1之間@property (readonly) double fractionCompleted;//取消- (void)cancel;//暫停- (void)pause;//恢復- (void)resume

六、關于NSProgress對象的用戶配置字典

在NSProgress對象的用戶字典中可以設置一些特定的鍵值來進行顯示模式的設置,示例如下:

//設置剩余時間 會影響localizedAdditionalDescription的值/*例如:0 of 10 ― About 10 seconds remaining*/[progress setUserInfoObject:@10 forKey:NSProgressEstimatedTimeRemainingKey];//設置完成速度信息 會影響localizedAdditionalDescription的值/*例如:Zero KB of 10 bytes (15 bytes/sec)*/[progress setUserInfoObject:@15 forKey:NSProgressThroughputKey];/*下面這些鍵值的生效 必須將NSProgress對象的kind屬性設置為 NSProgressKindFileNSProgressFileOperationKindKey鍵對應的是提示文字類型 會影響localizedDescription的值NSProgressFileOperationKindKey可選的對應值如下:NSProgressFileOperationKindDownloading: 顯示Downloading files…NSProgressFileOperationKindDecompressingAfterDownloading: 顯示Decompressing files…NSProgressFileOperationKindReceiving: 顯示Receiving files…NSProgressFileOperationKindCopying: 顯示Copying files…*/ [progress setUserInfoObject:NSProgressFileOperationKindDownloading forKey:NSProgressFileOperationKindKey];/*NSProgressFileTotalCountKey鍵設置顯示的文件總數 例如:Copying 100 files…*/ [progress setUserInfoObject:@100 forKey:NSProgressFileTotalCountKey];//設置已完成的數量[progress setUserInfoObject:@1 forKey:NSProgressFileCompletedCountKey];

七、在UI中顯示進度步驟總結
以下有幾個在視圖或者視圖控制器中顯示進度的步驟:
1.在你調用一個長時間運行的任務之前,借助+progressWithTotalUnitCount:.方法建立一個NSProgress實例。 參數totalUnitCount將會包括“要完成的總工作單元的數量”。
 
有一點很重要,要從UI圖層的角度完全理解這個數值;你不會被要求猜測有多少個實際工作對象以及有多少種類的工作單元(字節?像素?文字行數?)。如果你遍歷集合并且計劃為每一個集合元素調用該實例對象,該參數經常會是1或者也許是一個集合中的元素的數量 。
 
2.使用KVO注冊一個進度的fractionCompleted屬性的觀察者。類似于NSOperation,NSProgress被設計借助KVO來使用。在MAC,這使得通過Cocoa Bindings綁定一個NSProgress實例到一個進度條或者標簽上變得非常容易。在iOS上,你將會在KVO observer handle中手動更新你的UI。
 
除了fractionCompleted, completedUnitCount和totalUnitCount屬性之外,NSProgress也有一個localizedDescription (@"50% completed"),并且還有一個localized Additional Description (@"3 of 6"),其能夠被綁定到文本標簽。KVO通知在改變NSProgress對象屬性值的線程中發送,因此確保在你的主線程中手動更新UI。
 
3.當前的進度對象通過調用-becomeCurrentWithPendingUnitCount:方法建立新的進度對象。在這里,pendingUnitCount這個參數相當于“是要被接收者完成的總的工作單元的量要完成的工作的一部分”。你可以多次調用這個方法并且每次傳遞totalUnitCount(本次代碼完成的占比)的一部分。在集合元素的迭代示例中,我們將會在每一次迭代中調用[progress becomeCurrentWithPendingUnitCount:1];
 
4.調用工作對象的方法。由于當前進度是一個局部線程概念,你必須在你調用becomeCurrentWithPendingUnitCount:的相同的線程中做這個事情。如果工作對象的API被設計成在主線程中調用,那這就不是一個問題,就像我對大部分API的看法那樣(Brent Simmons 也這么認為)。
 
但是如果你的UI 層正在建立一個后臺隊列并且調用工作對象來同步那個隊列,那要確保將 becomeCurrentWithPendingUnitCount:和resignCurrent放到相同的dispatch_async()塊中調用。
 
5.在你的進度對象中調用-resignCurrent。這個方法是和-becomeCurrentWith PendingUnitCount:相對應的,并且會調用相同的次數 。你可以在實際工作被完成以前調用resignCurrent,因此你不需要等待,直到你得到一個來自工作對象的完成通知。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品国产高清自在线看超| 欧美激情亚洲综合一区| 国产精品久久久久91| 欧美国产视频一区二区| 欧美国产精品日韩| 高清一区二区三区四区五区| 国产亚洲美女久久| 91tv亚洲精品香蕉国产一区7ujn| 久久在线视频在线| 国产欧美精品一区二区三区-老狼| 一区二区三区回区在观看免费视频| 97国产精品视频人人做人人爱| 欧美一区二区三区四区在线| 久久精品视频在线播放| 欧美性高跟鞋xxxxhd| 清纯唯美日韩制服另类| 国产91成人在在线播放| 欧美日韩另类字幕中文| 久热精品视频在线| 性欧美xxxx交| 久久成人亚洲精品| 日韩乱码在线视频| 欧美巨乳美女视频| 精品久久久久久中文字幕一区奶水| 亚洲欧洲自拍偷拍| 久久91精品国产91久久久| 亚洲精品一二区| 日韩精品中文字幕在线| 亚洲美腿欧美激情另类| 91精品国产色综合| 久久久亚洲影院你懂的| 国外成人免费在线播放| 中文字幕久久亚洲| 欧美成人黑人xx视频免费观看| 国产亚洲精品久久久久久| 欧美视频在线免费| 欧美精品激情在线| 欧美日韩美女在线| 中文字幕精品国产| 久久久精品电影| 92福利视频午夜1000合集在线观看| 国产精品久久久久高潮| 久久视频免费观看| 午夜精品理论片| 久久久久久亚洲精品中文字幕| 欧美精品日韩www.p站| 日韩高清av在线| 国产激情久久久| 欧美另类99xxxxx| 色婷婷综合成人| 欧美国产乱视频| 久久久人成影片一区二区三区| 蜜月aⅴ免费一区二区三区| 久久久噜噜噜久久| 亚洲成色999久久网站| 日韩中文字幕不卡视频| 欧美精品在线观看91| 欧美成年人视频网站| 欧美一区二区三区图| 成人激情电影一区二区| 亚洲国产精品一区二区久| 成人国内精品久久久久一区| 国产视频精品久久久| 亚洲在线观看视频| 欧美噜噜久久久xxx| 国产美女91呻吟求| 亚洲成人免费在线视频| 久久全国免费视频| 日韩av影视在线| 免费不卡在线观看av| 在线午夜精品自拍| 日韩国产在线看| 亚洲人成电影网站色…| 国产精品视频xxx| 91精品久久久久久久久久久| 精品香蕉在线观看视频一| 国产91精品视频在线观看| 福利一区视频在线观看| 亚洲一区二区自拍| 精品一区电影国产| 国产精品久久不能| 欧美在线视频网| 精品久久久精品| 成人激情视频在线观看| 日本人成精品视频在线| 97精品国产97久久久久久春色| 久久久国产精品一区| 美女啪啪无遮挡免费久久网站| 国产啪精品视频| 国产美女精品视频| 亚洲激情小视频| 九九热这里只有精品免费看| 国产精品久久久久久亚洲影视| 久久精品中文字幕电影| 91精品国产91久久久久久吃药| 国产精品一二区| 91最新国产视频| 丝袜一区二区三区| 韩国v欧美v日本v亚洲| 午夜精品久久久久久久白皮肤| 国产成人精彩在线视频九色| 欧美日韩电影在线观看| 国语自产精品视频在线看抢先版图片| 日韩免费在线观看视频| 亚洲色图五月天| 亚洲欧洲一区二区三区久久| 高清在线视频日韩欧美| 久久亚洲国产精品| 国产精品九九久久久久久久| 亚洲aⅴ男人的天堂在线观看| 亚洲 日韩 国产第一| 国产精品久久久一区| 国内外成人免费激情在线视频网站| 国产一区二区三区久久精品| 久久九九有精品国产23| 亚洲社区在线观看| 国产精品免费一区| 2020国产精品视频| xxxx欧美18另类的高清| 国产午夜精品麻豆| 国产丝袜视频一区| 一区二区三区久久精品| 91影院在线免费观看视频| 亚洲一区二区在线| 国产一区二区动漫| 7777精品久久久久久| 九色91av视频| 国产va免费精品高清在线观看| 日韩精品一区二区三区第95| 国产精品日韩在线一区| 91精品国产91久久久久久吃药| 78m国产成人精品视频| 国产精自产拍久久久久久| 日本伊人精品一区二区三区介绍| 日韩欧美精品中文字幕| 欧美日韩成人在线观看| 成人免费淫片视频软件| 久久精品国产一区| 欧美极品欧美精品欧美视频| 亚洲欧洲在线观看| 亚洲一区二区三区在线视频| 欧美黑人巨大xxx极品| 911国产网站尤物在线观看| 欧美成人sm免费视频| 亚洲第一区中文99精品| 黑人与娇小精品av专区| 91沈先生在线观看| 午夜精品福利视频| 欧美一级淫片丝袜脚交| 欧美午夜影院在线视频| 色综合色综合久久综合频道88| 亚洲视频一区二区三区| 国产成人免费91av在线| 日韩经典中文字幕| 91综合免费在线| 夜夜狂射影院欧美极品| 国产精品一区二区久久久久| 久久深夜福利免费观看| 黑人巨大精品欧美一区二区免费| 欧美成aaa人片免费看| www.日本久久久久com.| 精品视频9999| 欧美精品情趣视频| 国产成人aa精品一区在线播放|