目錄[-]
這是一篇帶有一定筆者主觀感情色彩的比較文章.文章着重對比github上最流行的兩個iOS進度提示控件 MBProgressHUD 與 SVProgressHUD的各自優劣,來幫助初學者找到一個適合的iOS提示框解決方案.
無論如何,你總是需要一個提示框.
提示框,進度提示,加載中提示等等,無論怎樣,你總是需要提示框來指示某個狀態正在後臺努力進行中.一個合適的提示框,更多的是用來增強用戶體驗.把最多的時間,用來做更核心的事;把這些不是非常重要的事,你應該試着使用一個成熟穩定的第三方來解決.
MBProgressHUD 還是 SVProgressHUD ?
許多時候,選擇都是很重要的,但是總是要做出選擇.每個人考慮的因素和角度不同,結論或許也不同.但是,你要明白,你現在是要找一個合適的方案來解決自己的關於"提示框"的需求,而不是去無意義的討論與分析.我推薦你使用 MBProgressHUD. 如果你只是想找一個方案,看到這裏就夠了.下面會進行一些對比分析.有時候,羅列一些可選方案,總是讓人感覺很舒服的;但是我們最終都要做出選擇,表明自己的態度.就像你可以依然堅持自己的看法,我會依然深度使用 MBProgressHUD一樣.下面的分析不是要證明 MBProgressHUD 或 SVProgressHUD 誰好或者不好,更多的只是爲了說明,我的選擇可能不是最佳的,但還是靠點譜的!
github 流行度: MBProgressHUD - SVProgressHUD = 2500
截止目前, MBProgressHUD 的關注度爲 8556, SVProgressHUD 的關注度爲 6003,差額在 2500左右.github上面的流行度是很能說明兩個第三方的相對優劣的,這就像各個書店上圖書的購買量和評論量總是和一本書的價值成正相關一樣!誠然, MBProgressHUD 和 SVProgressHUD 的關注度都是非常高的了,都已經屬於非常流行的 iOS 第三方了.但是,既然我要選一個深度使用,肯定是關注度更高的那個!在大多數時候,我相信"大家"的選擇,對自己是可有參考價值的!
接口易用性: MBProgressHUD == SVProgressHUD
以下是MBProgressHUD 和 SVProgressHUD 各自項目的github主頁上,各自的基本用法示例:
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do something...
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
});
[SVProgressHUD show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// time-consuming task
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
});
在大多數場景中,你幾乎只會用到顯示
與隱藏
這兩個最基本的方法,所以說,儘管
SVProgressHUD 自稱更加易用,但是我還是認爲這真的看不出什麼優勢.
接口豐富性: MBProgressHUD >> SVProgressHUD
MBProgressHUD 和 SVProgressHUD 都支持簡單的進度提示和文字提示.單從各自github主頁上來看, SVProgressHUD 似乎擁有更多的接口,但是事實並非如此.如果你下載過MBProgressHUD的示例就會發現,它能實現的功能要遠遠多於 文檔示例給出的簡單的 顯示
與 隱藏
.爲了能讓大家更多的瞭解MBProgressHUD,列出部分方法與參數常量,具體信息可參考官方示例:
/**
* 創建一個新的HUD,並把它添加並顯示到提供的視圖上.與之相對應的方法是 hideHUDForView:animated:.
*
* @note 這個方法會設置HUD的屬性`removeFromSuperViewOnHide`爲YES.HUD會在隱藏時自動從父視圖上移除.
*
* @param view 將HUD添加到此視圖上.
* @param animated YES,顯示時使用當前的動畫類型顯示;NO,直接顯示不使用動畫效果.
* @return 新創建的HUD.
*
* @see hideHUDForView:animated:
* @see animationType
*/
+ (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
/**
* 找到並隱藏子視圖最頂層的HUD.與之對應的方法是 showHUDAddedTo:animated:.
*
* @note 這個方法會設置HUD的屬性`removeFromSuperViewOnHide`爲YES.HUD會在隱藏時自動從父視圖上移除.
*
* @param view 用來在其子視圖中查找HUD的視圖.
* @param animated YES,隱藏時使用當前的動畫類型顯示;NO,直接隱藏不使用動畫效果.
* @return YES,如果某個HUD被找到並被移除;否則返回NO.
*
* @see showHUDAddedTo:animated:
* @see animationType
*/
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
/**
* 找到子視圖中所有的HUD,並隱藏.
*
* @note 這個方法會設置HUD的屬性`removeFromSuperViewOnHide`爲YES.HUD會在隱藏時自動從父視圖上移除.
*
* @param view 用來在其子視圖中查找HUD的視圖.
* @param animated YES,隱藏時使用當前的動畫類型顯示;NO,直接隱藏不使用動畫效果.
* @return 找到並移除的HUD的數量.
*
* @see hideHUDForView:animated:
* @see animationType
*/
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated;
/**
* 找到並返回子視圖最頂層的HUD.
*
* @param view 用來在其子視圖中查找HUD的視圖.
* @return 子視圖最頂層的HUD.
*/
+ (MB_INSTANCETYPE)HUDForView:(UIView *)view;
/**
* 找到並返回子視圖中所有的HUD.
*
* @param view 用來在其子視圖中查找HUD的視圖.
* @return 所有找到的HUD視圖(存儲 MBProgressHUD 對象的數組).
*/
+ (NSArray *)allHUDsForView:(UIView *)view;
/**
* 使用屏幕尺寸創建HUD的便利初始化方法.
*
* @param window 提供邊框值以初始化HUD的窗口.應該和HUD未來的父視圖相同(比如,創建 HUD 後,將HUD添加到此窗口上).
*/
- (id)initWithWindow:(UIWindow *)window;
/**
* 使用指定視圖的邊框尺寸創建HUD的便利初始化方法.
*
* @param view 提供邊框值以初始化HUD的視圖.應該和HUD未來的父視圖相同(比如,創建 HUD 後,將HUD添加到此視圖上).
*/
- (id)initWithView:(UIView *)view;
/**
* 顯示HUD.你需要確保調用此方法時,主線程未被其他任務阻塞,以便於更新視圖.當你已經在新的線程中開始(比如,使用NSOperation或者NSURLRequest的異步請求等)執行某個任務後,再執行此方法.
*
* @param animated YES,顯示時使用當前的動畫類型顯示;NO,直接顯示不使用動畫效果. *
* @see animationType
*/
- (void)show:(BOOL)animated;
/**
* 隱藏HUD.這個仍然會去嘗試調用代理的hudWasHidden:方法.此方法是 show: 的配對方法.當你的任務完成時,再使用它.
*
* @param animated YES,隱藏時使用當前的動畫類型顯示;NO,直接隱藏不使用動畫效果.
*
* @see animationType
*/
- (void)hide:(BOOL)animated;
/**
* 延時隱藏HUD.這個仍然會去嘗試調用代理的hudWasHidden:方法.此方法是 show: 的配對方法.當你的任務完成時,再使用它.
* *
* @param animated YES,隱藏時使用當前的動畫類型顯示;NO,直接隱藏不使用動畫效果.
* @param delay Delay in seconds until the HUD is hidden.
*
* @see animationType
*/
- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay;
/**
* 當在新線程執行某個後臺任務時,顯示HUD;任務完成時,自動隱藏HUD.
*
* 這個方法會處理自動釋放池的相關技術細節,所以你可以安全使用它.
*
* @param method HUD顯示期間,被執行的方法.這個方法會在一個新的線程中執行.
* @param target HUD顯示期間,被調用的方法歸屬的實例對象.
* @param object 用來傳遞給方法的可選對象.
* @param animated YES,HUD使用當前的 animationType 動畫類型來顯示或隱藏;否則,顯示或隱藏時不使用動畫效果.
* animations while (dis)appearing.
*/
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;
#if NS_BLOCKS_AVAILABLE
/**
* 當在後臺隊列中執行block時,顯示HUD;並在block執行完畢後,隱藏HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block;
/**
* 當在後臺隊列中執行block時,顯示HUD;並在block執行完畢後,隱藏HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(MBProgressHUDCompletionBlock)completion;
/**
* 當在後臺隊列中執行block時,顯示HUD;並在block執行完畢後,隱藏HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue;
/**
* 當在一個指定的隊列中執行block時,顯示HUD;block執行完畢後在主線程執行completion block;然後隱藏HUD.
*
* @param animated YES,HUD使用當前的 animationType 動畫類型來顯示或隱藏;否則,顯示或隱藏時不使用動畫效果.
* @param block HUD顯示期間執行的block.
* @param queue block在此隊列中執行.
* @param completion 完成時執行的block.
*
* @see completionBlock
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
completionBlock:(MBProgressHUDCompletionBlock)completion;
接口靈活性和可擴展性: MBProgressHUD > SVProgressHUD
首先,二者都是開放源代碼的,如果有特殊需求,可以完全自主定製;所以這裏主要討論的是 MBProgressHUD 和 SVProgressHUD自身在不修改核心代碼的前提下的接口靈活性和可擴展性.同樣的但從文檔來看, SVProgressHUD 表現出更多的靈活性,參見: SVProgressHUD–比MBProgressHUD更好用的 iOS進度提示組件.但是事實並非如此! MBProgressHUD 入門文檔相對很少提及其靈活性,但其提供的DEMO中較完整地展示了它的強大之處.個人認爲,單單允許使用自定義視圖作爲提供框的視圖這一點,就足以讓SVProgressHUD 的絕大部分特性黯然失色;這也是我最終決定選定 MBProgressHUD 並深入使用 MBProgressHUD的重要原因.初次之外, MBProgressHUD 還支持自定義部分進度條相關的屬性.具體細節如下:
@interface MBProgressHUD : UIView
/**
* HUD完全隱藏後執行的block.
*/
@property (copy) MBProgressHUDCompletionBlock completionBlock;
/**
* MBProgressHUD 操作模式. 默認是 MBProgressHUDModeIndeterminate.
*
* @see MBProgressHUDMode
*/
@property (assign) MBProgressHUDMode mode;
/**
* HUD顯示和隱藏時使用的動畫類型.
*
* @see MBProgressHUDAnimation
*/
@property (assign) MBProgressHUDAnimation animationType;
/**
* HUD處於MBProgressHUDModeCustomView模式時,顯示此自定義視圖(比如一個 UIImageView).
* 最好設置自定義視圖寬高爲 37x37(這是HUD內建指示器的邊框值).
*/
@property (MB_STRONG) UIView *customView;
/**
* HUD代理對象.
*
* @see MBProgressHUDDelegate
*/
@property (MB_WEAK) id<MBProgressHUDDelegate> delegate;
/**
*狀態指示器下可選顯示的短消息.HUD會自動調整文字的尺寸. 如果文字過長,後面會用"..."代替.
*/
@property (copy) NSString *labelText;
/**
* 可選顯示在labelText的細節文字信息.支持多行顯示.
*/
@property (copy) NSString *detailsLabelText;
/**
* HUD的不透明度.默認是0.8.
*/
@property (assign) float opacity;
/**
* HUD的顏色.默認黑色.設置此值後, opacity屬性的值將不再使用,因爲顏色也可以設置透明度.
*/
@property (MB_STRONG) UIColor *color;
/**
* HUD相對於父視圖中心點的水平偏移量.
*/
@property (assign) float xOffset;
/**
* HUD相對於父視圖中心點的垂直偏移量.
*/
@property (assign) float yOffset;
/**
* HUD邊緣與HUD的元素之間(比如標籤,指示器,自定義視圖等)的空白距離.
* 默認 20.0
*/
@property (assign) float margin;
/**
* HUD圓角半徑,默認10.0.
*/
@property (assign) float cornerRadius;
/**
* 是否給父視圖添加一個放射線樣式的遮罩層.默認NO.
*/
@property (assign) BOOL dimBackground;
/*
* 用於指定某個方法執行一段時間之後再顯示HUD,以秒記.如果方法在這段時間之前就執行完成,就不再顯示HUD.
* 這主要是爲了優化耗時可能極短的任務的體驗.
* 默認值爲 0.
* 這個屬性僅在可以任務的狀態可以知曉時,纔有作用.
* @see taskInProgress
*/
@property (assign) float graceTime;
/**
* HUD顯示的最小時間(以秒記.)
* 這可以避免HUD剛一顯示立即又隱藏所帶來的不好的用戶體驗.
* 默認是 0.
*/
@property (assign) float minShowTime;
/**
* 指示被執行的操作是否還在執行. graceTime 屬性依賴於這個屬性.
* 如果你沒有設置graceTime(和設置爲0.0不同),這個屬性沒有任何作用.
* 當使用showWhileExecuting:onTarget:withObject:animated:時,這個值會被自動設置.
* 當直接使用show:或hide:等方法顯示或隱藏HUD時,你應該手動設置taskInProgress 屬性的值,以保證 graceTime 能正確發揮作用.
*/
@property (assign) BOOL taskInProgress;
/**
* HUD隱藏時,是否從父視圖中移除.
* 默認 NO.
*/
@property (assign) BOOL removeFromSuperViewOnHide;
/**
* 用於主標籤的字體值.
*/
@property (MB_STRONG) UIFont* labelFont;
/**
* 主標籤顏色值.
*/
@property (MB_STRONG) UIColor* labelColor;
/**
* 詳情標籤字體值.
*/
@property (MB_STRONG) UIFont* detailsLabelFont;
/**
* 詳情標籤顏色.
*/
@property (MB_STRONG) UIColor* detailsLabelColor;
/**
* 指示器顏色.默認 [UIColor whiteColor]
*/
@property (MB_STRONG) UIColor *activityIndicatorColor;
/**
* 進度指示器的顏色,可選 0.0 ~ 1.0,默認0.0.
*/
@property (assign) float progress;
/**
* HUD面板的最小尺寸.默認 CGSizeZero.
*/
@property (assign) CGSize minSize;
/**
* HUD面板的實際尺存,只讀.
* 你可以使用它來限制HUD的可點擊區域.
* @see https://github.com/jdg/MBProgressHUD/pull/200
*/
@property (atomic, assign, readonly) CGSize size;
/**
* 是否強制設置HUD爲正方形,默認NO.
*/
@property (assign, getter = isSquare) BOOL square;
@end
@protocol MBProgressHUDDelegate <NSObject>
@optional
/**
* HUD完全從屏幕中隱藏時調用此方法.
*/
- (void)hudWasHidden:(MBProgressHUD *)hud;
@end
/**
* 一個餅狀圖樣式的進圖指示視圖.
*/
@interface MBRoundProgressView : UIView
/**
* 進度 (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* 進度指示器顏色.默認 [UIColor whiteColor].
*/
@property (nonatomic, MB_STRONG) UIColor *progressTintColor;
/**
* 進度指示的背景部分的顏色.
* 默認白色半透(透明度0.1)
*/
@property (nonatomic, MB_STRONG) UIColor *backgroundTintColor;
/*
* 顯示模式.NO,圓形;YES,環形.默認圓形.
*/
@property (nonatomic, assign, getter = isAnnular) BOOL annular;
@end
/**
* 一個水平進度條視圖.
*/
@interface MBBarProgressView : UIView
/**
* 進度 (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* 進度條邊框線的顏色.
* 默認白色 [UIColor whiteColor].
*/
@property (nonatomic, MB_STRONG) UIColor *lineColor;
/**
* 進度條背景色.
* 默認是 [UIColor clearColor];
*/
@property (nonatomic, MB_STRONG) UIColor *progressRemainingColor;
/**
* 進度的顏色.
* 默認 [UIColor whiteColor].
*/
@property (nonatomic, MB_STRONG) UIColor *progressColor;
@end
結論
總而言之, 不管你開發什麼應用,你總是需要一個MBProgressHUD,而我真的推薦你使用 MBProgressHUD.官方文檔對MBProgressHUD的具體功能提的過於精簡,希望能借助這篇文章,能讓大家一起更全面的認識 MBProgressHUD.