最近海芋開始開發 iOS 程式,而在開發程式時,難免會遇到需要等待的程式碼,如下載進度,或者串接 Web Service 的服務,如果沒有一個等待的通知給使用者,會讓使用者有當機或者不好的使用經驗。「SVProgressHUD」則是一個進度顯示工具,有點像是 Android 的 Progress Bar,不同的是,SVProgressHUD 是以圓型進度工具顯示,相當符合 iOS 的設計風格,如果在找 Android Progress Bar 代替品的朋友,可以趕緊下載這個程式碼來開發您的 iOS 程式。
在使用這個第三方套件前,我們先來看一下使用 SVProgressHUD 所呈現的效果,預設是六種效果。
底下是「show」,只是單純轉圈圈。
底下是「show with status」,除了轉圈圈外,還可以在進度下方加上文字。
底下是「show with Progress」,這個有進度外,還可以在進度下方加上文字,比較接近 Android 中的 Progress Bar。
底下這三種我歸類為同一種,分別是顯示資訊、顯示成功狀態、顯示錯誤狀態。
顯示成功狀態。
顯示錯誤訊息。
要用 SVProgressHUD 的方式也很簡單,官方的範例就有了,以「showWithProgress」來說,官方是寫成這樣,每 0.3 秒就會自動把進度加 10%,一直到 100% 為止就關閉。
- (IBAction)showWithProgress:(id)sender {
progress = 0.0f;
[SVProgressHUD showProgress:0 status:@"Loading"];
[self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.3f];
}
- (void)increaseProgress {
progress+=0.1f;
[SVProgressHUD showProgress:progress status:@"Loading"];
if(progress < 1.0f)
[self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.3f];
else
[self performSelector:@selector(dismiss) withObject:nil afterDelay:0.4f];
}
不過由於官方的程式是在 Main Thread 做事情,有可能程式會需要在背景做資料處理及畫面更新,所以海芋用到了「dispatch_async」來開背景處理。
- (IBAction)showWithProgress:(id)sender
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 1; i <= 100 i++){
//更新 UIThread
dispatch_async(dispatch_get_main_queue(), ^{
float progress = (float) (i) /100;
[SVProgressHUD showProgress:(progress)
status: [NSString stringWithFormat:@"資料刪除中…"]];
});
[NSThread sleepForTimeInterval:0.01f]; //刪除每筆資料間隔 0.01 sec
}
dispatch_async(dispatch_get_main_queue(), ^{
[self performSelector: @selector(dismissDialog) withObject:nil afterDelay:0.4f];
}
}
- (void) dismissDialog
{
[SVProgressHUD dismiss];
}
上面為一段程式碼,當我們在刪除資料完成後,可以使用「dispatch_get_main_queue」來通知主畫面來更新進度,值得注意的是,當海芋拿掉「[NSThread sleepForTimeInterval:0.01f]; 」這段程式碼時,畫面不會更新,有可能是程式跑太快了,也有可能是因為 Thread 沒有暫停所致,但無論如何,在刪除大量資料時,本來就應該要停一下,讓 Server 不會如此操勞。
而如果你是程式設計師,相信以上你應該有感到一點興趣,甚至可以去 SVProgressHUD 下載程式碼來玩玩,如果你不是程式設計師,那麼這一篇文章對你來說,應該就可以略過囉!
以下是 SVProgressHUD 所有的函式,功能相當豐富,可以自行研究一下。
#pragma mark - Customization
+ (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor]
+ (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor]
+ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt
+ (void)setRingThickness:(CGFloat)width; // default is 4 pt
+ (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
+ (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik
+ (void)setSuccessImage:(UIImage*)image; // default is the bundled success image provided by Freepik
+ (void)setErrorImage:(UIImage*)image; // default is the bundled error image provided by Freepik
+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone
+ (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set
#pragma mark - Show Methods
+ (void)show;
+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType;
+ (void)showWithStatus:(NSString*)status;
+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress;
+ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress status:(NSString*)status;
+ (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
+ (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing
// stops the activity indicator, shows a glyph + status, and dismisses HUD a little bit later
+ (void)showInfoWithStatus:(NSString *)string;
+ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;
+ (void)showSuccessWithStatus:(NSString*)string;
+ (void)showSuccessWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType;
+ (void)showErrorWithStatus:(NSString *)string;
+ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;
// use 28x28 white pngs
+ (void)showImage:(UIImage*)image status:(NSString*)status;
+ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
+ (void)setOffsetFromCenter:(UIOffset)offset;
+ (void)resetOffsetFromCenter;
+ (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed
+ (void)dismiss;
+ (BOOL)isVisible;