源碼來源:gitHub源碼? ? 轉載于: CocoaChina? ? 來源:南峰子的技術博客
版本:0.9.1
MBProgressHUD是一個顯示HUD窗口的第三方類庫,用于在執(zhí)行一些后臺任務時,在程序中顯示一個表示進度的loading視圖和兩個可選的文本提示的HUD窗口。我想最多是應用在加載網(wǎng)絡數(shù)據(jù)的時候。其實蘋果官方自己有一個帶有此功能的類UIProgressHUD话告,只不過它是私有的,現(xiàn)在不讓用。至于實際的效果犹褒,可以看看github上工程給出的幾張圖例(貌似我這經(jīng)常無法單獨打開圖片,所以就不在這貼圖片了)弛针,也可以運行一下Demo叠骑。
具體用法我們就不多說了,參考github上的說明就能用得很順的削茁。本文主要還是從源碼的角度來分析一下它的具體實現(xiàn)宙枷。
模式
在分析實現(xiàn)代碼之前,我們先來看看MBProgressHUD中定義的MBProgressHUDMode枚舉付材。它用來表示HUD窗口的模式朦拖,即我們從效果圖中看到的幾種顯示樣式。其具體定義如下:
typedef enum {
// 使用UIActivityIndicatorView來顯示進度厌衔,這是默認值
MBProgressHUDModeIndeterminate,
// 使用一個圓形餅圖來作為進度視圖
MBProgressHUDModeDeterminate,
// 使用一個水平進度條
MBProgressHUDModeDeterminateHorizontalBar,
// 使用圓環(huán)作為進度條
MBProgressHUDModeAnnularDeterminate,
// 顯示一個自定義視圖璧帝,通過這種方式,可以顯示一個正確或錯誤的提示圖
MBProgressHUDModeCustomView,
// 只顯示文本
MBProgressHUDModeText
} MBProgressHUDMode;
通過設置MBProgressHUD的模式富寿,我們可以使用MBProgressHUD自定義的表示進度的視圖來滿足我們的需求睬隶,也可以自定義這個進度視圖,當然還可以只顯示文本页徐。在下面我們會討論源碼中是如何使用這幾個值的苏潜。
外觀
我們先來了解一下MBProgressHUD的基本組成。一個MBProgressHUD視圖主要由四個部分組成:
loading動畫視圖(在此做個統(tǒng)稱变勇,當然這個區(qū)域可以是自定義的一個UIImageView視圖)恤左。這個視圖由我們設定的模式值決定,可以是菊花搀绣、進度條飞袋,也可以是我們自定義的視圖;
標題文本框(label):主要用于顯示提示的主題信息链患。這個文本框是可選的巧鸭,通常位于loading動畫視圖的下面,且它是單行顯示麻捻。它會根據(jù)labelText屬性來自適應文本的大小(有一個長度上限)纲仍,如果過長呀袱,則超出的部分會顯示為”…“;
詳情文本框(detailsLabel)郑叠。如果覺得標題不夠詳細夜赵,或者有附屬信息,就可以將詳細信息放在這里面顯示锻拘。該文本框對應的是顯示detailsLabelText屬性的值油吭,它是可以多行顯示的。另外署拟,詳情的顯示還依賴于labelText屬性的設置婉宰,只有l(wèi)abelText屬性被設置了,且不為空串推穷,才會顯示detailsLabel心包;
HUD背景框。主要是作為上面三個部分的一個背景馒铃,用來突出上面三部分蟹腾。
為了讓我們更好地自定義這幾個部分,MBProgressHUD還提供了一些屬性区宇,我們簡單了解一下:
// 背景框的透明度娃殖,默認值是0.8
@property (assign) float opacity;
// 背景框的顏色
// 需要注意的是如果設置了這個屬性,則opacity屬性會失效议谷,即不會有半透明效果
@property (MB_STRONG) UIColor *color;
// 背景框的圓角半徑炉爆。默認值是10.0
@property (assign) float cornerRadius;
// 標題文本的字體及顏色
@property (MB_STRONG) UIFont* labelFont;
@property (MB_STRONG) UIColor* labelColor;
// 詳情文本的字體及顏色
@property (MB_STRONG) UIFont* detailsLabelFont;
@property (MB_STRONG) UIColor* detailsLabelColor;
// 菊花的顏色,默認是白色
@property (MB_STRONG) UIColor *activityIndicatorColor;
通過以上屬性卧晓,我們可以根據(jù)自己的需要來設置這幾個部分的外觀芬首。
另外還有一個比較有意思的屬性是dimBackground,用于為HUD窗口的視圖區(qū)域覆蓋上一層徑向漸變(radial gradient)層逼裆,其定義如下:
@property (assign) BOOL dimBackground;
讓我們來看看通過它郁稍,MBProgressHUD都做了些什么。代碼如下:
- (void)drawRect:(CGRect)rect {
...
if (self.dimBackground) {
//Gradient colours
size_t gradLocationsNum = 2;
CGFloat gradLocations[2] = {0.0f, 1.0f};
CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);
CGColorSpaceRelease(colorSpace);
//Gradient center
CGPoint gradCenter= CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
//Gradient radius
float gradRadius = MIN(self.bounds.size.width , self.bounds.size.height) ;
// 由中心向四周繪制漸變
CGContextDrawRadialGradient (context, gradient, gradCenter,
0, gradCenter, gradRadius,
kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
}
...
}
這段代碼由中心向MBProgressHUD視圖的四周繪制了一個漸變層胜宇。當然耀怜,這里的顏色值是寫死的,我們無法自行定義桐愉。有興趣的話封寞,大家可以將這個屬性設置為YES,看看實際的效果仅财。
創(chuàng)建、布局與繪制
除了繼承自UIView的-initWithFrame:初始化方法碗淌,MBProgressHUD還為我們提供了兩個初始化方法盏求,如下所示:
- (id)initWithWindow:(UIWindow *)window;
- (id)initWithView:(UIView *)view;
這兩個方法分別傳入一個UIWindow對象和一個UIView對象抖锥。傳入的視圖對象僅僅是做為MBProgressHUD視圖定義其frame屬性的參照,而不會直接將MBProgressHUD視圖添加到傳入的視圖對象上碎罚。這個添加操作還得我們自行處理(當然磅废,MBProgressHUD還提供了幾個便捷的類方法,我們下面會說明)荆烈。
MBProgressHUD提供了幾個屬性拯勉,可以讓我們控制HUD的布局,這些屬性主要有以下幾個:
// HUD相對于父視圖中心點的x軸偏移量和y軸偏移量
@property (assign) float xOffset;
@property (assign) float yOffset;
// HUD各元素與HUD邊緣的間距
@property (assign) float margin;
// HUD背景框的最小大小
@property (assign) CGSize minSize;
// HUD的實際大小
@property (atomic, assign, readonly) CGSize size;
// 是否強制HUD背景框寬高相等
@property (assign, getter = isSquare) BOOL square;
需要注意的是憔购,MBProgressHUD視圖會充滿其父視圖的frame內宫峦,為此,在MBProgressHUD的layoutSubviews方法中玫鸟,還專門做了處理导绷,如下代碼所示:
- (void)layoutSubviews {
[super layoutSubviews];
// Entirely cover the parent view
UIView *parent = self.superview;
if (parent) {
self.frame = parent.bounds;
}
...
}
也因此,當MBProgressHUD顯示時屎飘,它也會屏蔽父視圖的各種交互操作妥曲。
在布局的過程中,會先根據(jù)我們要顯示的視圖計算出容納這些視圖所需要的總的寬度和高度钦购。當然檐盟,會設置一個最大值。我們截取其中一段來看看:
CGRect bounds = self.bounds;
...
CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
CGSize detailsLabelSize = MB_MULTILINE_TEXTSIZE(detailsLabel.text, detailsLabel.font, maxSize, detailsLabel.lineBreakMode);
totalSize.width = MAX(totalSize.width, detailsLabelSize.width);
totalSize.height += detailsLabelSize.height;
if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
totalSize.height += kPadding;
}
totalSize.width += 2 * margin;
totalSize.height += 2 * margin;
之后押桃,就開始從上到下放置各個視圖葵萎。在布局代碼的最后,計算了一個size值怨规,這是為后面繪制背景框做準備的陌宿。
在上面的布局代碼中,主要是處理了loading動畫視圖波丰、標題文本框和詳情文本框壳坪,而HUD背景框主要是在drawRect:中來繪制的。背景框的繪制代碼如下:
// Center HUD
CGRect allRect = self.bounds;
// Draw rounded HUD backgroud rect
CGRect boxRect = CGRectMake(round((allRect.size.width - size.width) / 2) + self.xOffset,
round((allRect.size.height - size.height) / 2) + self.yOffset, size.width, size.height);
float radius = self.cornerRadius;
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect));
CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0);
CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0);
CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0);
CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0);
CGContextClosePath(context);
CGContextFillPath(context);
這是最平常的繪制操作掰烟,在此不多做解釋爽蝴。
我們上面講過MBProgressHUD提供了幾種窗口模式,這幾種模式的主要區(qū)別在于loading動畫視圖的展示纫骑。默認情況下蝎亚,使用的是菊花(MBProgressHUDModeIndeterminate)。我們可以通過設置以下屬性先馆,來改變loading動畫視圖:
@property (assign) MBProgressHUDMode mode;
對于其它幾種模式发框,MBProgressHUD專門我們提供了幾個視圖類。如果是進度條模式(MBProgressHUDModeDeterminateHorizontalBar)煤墙,則使用的是MBBarProgressView類梅惯;如果是餅圖模式(MBProgressHUDModeDeterminate)或環(huán)形模式(MBProgressHUDModeAnnularDeterminate)宪拥,則使用的是MBRoundProgressView類。上面這兩個類的主要操作就是在drawRect:中根據(jù)一些進度參數(shù)來繪制形狀铣减,大家可以自己詳細看一下她君。
當然,我們還可以自定義loading動畫視圖葫哗,此時選擇的模式是MBProgressHUDModeCustomView缔刹。或者不顯示loading動畫視圖劣针,而只顯示文本框(MBProgressHUDModeText)校镐。
具體顯示哪一種loading動畫視圖,是在-updateIndicators方法中來處理的酿秸,其實現(xiàn)如下所示:
- (void)updateIndicators {
BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];
BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];
if (mode == MBProgressHUDModeIndeterminate) {
...
}
else if (mode == MBProgressHUDModeDeterminateHorizontalBar) {
// Update to bar determinate indicator
[indicator removeFromSuperview];
self.indicator = MB_AUTORELEASE([[MBBarProgressView alloc] init]);
[self addSubview:indicator];
}
else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) {
if (!isRoundIndicator) {
...
}
if (mode == MBProgressHUDModeAnnularDeterminate) {
[(MBRoundProgressView *)indicator setAnnular:YES];
}
}
else if (mode == MBProgressHUDModeCustomView && customView != indicator) {
...
} else if (mode == MBProgressHUDModeText) {
...
}
}
顯示與隱藏
MBRoundProgressView為我們提供了豐富的顯示與隱藏HUD窗口的灭翔。在分析這些方法之前,我們先來看看MBProgressHUD為顯示與隱藏提供的一些屬性:
// HUD顯示和隱藏的動畫類型
@property (assign) MBProgressHUDAnimation animationType;
// HUD顯示的最短時間辣苏。設置這個值是為了避免HUD顯示后立即被隱藏肝箱。默認值為0
@property (assign) float minShowTime;
// 這個屬性設置了一個寬限期,它是在沒有顯示HUD窗口前被調用方法可能運行的時間稀蟋。
// 如果被調用方法在寬限期內執(zhí)行完煌张,則HUD不會被顯示。
// 這主要是為了避免在執(zhí)行很短的任務時退客,去顯示一個HUD窗口骏融。
// 默認值是0。只有當任務狀態(tài)是已知時萌狂,才支持寬限期档玻。具體我們看實現(xiàn)代碼。
@property (assign) float graceTime;
// 這是一個標識位茫藏,標明執(zhí)行的操作正在處理中误趴。這個屬性是配合graceTime使用的。
// 如果沒有設置graceTime务傲,則這個標識是沒有太大意義的凉当。在使用showWhileExecuting:onTarget:withObject:animated:方法時,
// 會自動去設置這個屬性為YES售葡,其它情況下都需要我們自己手動設置看杭。
@property (assign) BOOL taskInProgress;
// 隱藏時是否將HUD從父視圖中移除,默認是NO挟伙。
@property (assign) BOOL removeFromSuperViewOnHide;
// 進度指示器楼雹,從0.0到1.0,默認值為0.0
@property (assign) float progress;
// 在HUD被隱藏后的回調
@property (copy) MBProgressHUDCompletionBlock completionBlock;
以上這些屬性都還好理解,可能需要注意的就是graceTime和taskInProgress的配合使用烘豹。在下面我們將會看看這兩個屬性的用法瓜贾。
對于顯示操作,最基本的就是-show:方法(其它幾個顯示方法都會調用該方法來顯示HUD窗口)携悯,我們先來看看它的實現(xiàn),
- (void)show:(BOOL)animated {
useAnimation = animated;
// If the grace time is set postpone the HUD display
if (self.graceTime > 0.0) {
self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime target:self
selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];
}
// ... otherwise show the HUD imediately
else {
[self showUsingAnimation:useAnimation];
}
}
可以看到筷笨,如果我們沒有設置graceTime屬性憔鬼,則會立即顯示HUD;而如果設置了graceTime胃夏,則會創(chuàng)建一個定時器轴或,并讓顯示操作延遲到graceTime所設定的時間再執(zhí)行,而-handleGraceTimer:實現(xiàn)如下:
- (void)handleGraceTimer:(NSTimer *)theTimer {
// Show the HUD only if the task is still running
if (taskInProgress) {
[self showUsingAnimation:useAnimation];
}
}
可以看到仰禀,只有在設置了taskInProgress標識位為YES的情況下照雁,才會去顯示HUD窗口。所以答恶,如果我們要自己調用-show:方法的話饺蚊,需要酌情考慮設置taskInProgress標識位。
除了-show:方法以外悬嗓,MBProgressHUD還為我們提供了一組顯示方法污呼,可以讓我們在顯示HUD的同時,執(zhí)行一些后臺任務包竹,我們在此主要介紹兩個燕酷。其中一個是-showWhileExecuting:onTarget:withObject:animated:,它是基于target-action方式的調用周瞎,在執(zhí)行一個后臺任務時顯示HUD苗缩,等后臺任務執(zhí)行完成后再隱藏HUD,具體實現(xiàn)如下所示:
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {
methodForExecution = method;
targetForExecution = MB_RETAIN(target);
objectForExecution = MB_RETAIN(object);
// Launch execution in new thread
self.taskInProgress = YES;
[NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
// Show HUD view
[self show:animated];
}
- (void)launchExecution {
@autoreleasepool {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Start executing the requested task
[targetForExecution performSelector:methodForExecution withObject:objectForExecution];
#pragma clang diagnostic pop
// Task completed, update view in main thread (note: view operations should
// be done only in the main thread)
[self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];
}
}
可以看到声诸,-showWhileExecuting:onTarget:withObject:animated:首先將taskInProgress屬性設置為YES酱讶,這樣在調用-show:方法時,即使設置了graceTime双絮,也確保能在任務完成之前顯示HUD浴麻。然后開啟一個新線程,來異步執(zhí)行我們的后臺任務囤攀,最后去顯示HUD软免。
而在異步調用方法-launchExecution中,線程首先是維護了自己的一個@autoreleasepool焚挠,所以在我們自己的方法中膏萧,就不需要再去維護一個@autoreleasepool了。之后是去執(zhí)行我們的任務,在任務完成之后榛泛,再回去主線程去執(zhí)行清理操作蝌蹂,并隱藏HUD窗口。
另一個顯示方法是-showAnimated:whileExecutingBlock:onQueue:completionBlock:曹锨,它是基于GCD的調用孤个,當block中的任務在指定的隊列中執(zhí)行時,顯示HUD窗口沛简,任務完成之后執(zhí)行completionBlock操作齐鲤,最后隱藏HUD窗口。我們來看看它的具體實現(xiàn):
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
completionBlock:(MBProgressHUDCompletionBlock)completion {
self.taskInProgress = YES;
self.completionBlock = completion;
dispatch_async(queue, ^(void) {
block();
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self cleanUp];
});
});
[self show:animated];
}
這個方法也是首先將taskInProgress屬性設置為YES椒楣,然后開啟一個線程去執(zhí)行block任務给郊,最后主線程去執(zhí)行清理操作,并隱藏HUD窗口捧灰。
對于HUD的隱藏淆九,MBProgressHUD提供了兩個方法,一個是-hide:毛俏,另一個是-hide:afterDelay:炭庙,后者基于前者,所以我們主要來看看-hide:的實現(xiàn):
- (void)hide:(BOOL)animated {
useAnimation = animated;
// If the minShow time is set, calculate how long the hud was shown,
// and pospone the hiding operation if necessary
if (self.minShowTime > 0.0 && showStarted) {
NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted];
if (interv < self.minShowTime) {
self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) target:self
selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];
return;
}
}
// ... otherwise hide the HUD immediately
[self hideUsingAnimation:useAnimation];
}
我們可以看到拧抖,在設置了minShowTime屬性并且已經(jīng)顯示了HUD窗口的情況下煤搜,會去判斷顯示的時間是否小于minShowTime指定的時間,如果是唧席,則會開啟一個定時器擦盾,等到顯示的時間到了minShowTime所指定的時間,才會去隱藏HUD窗口淌哟;否則會直接去隱藏HUD窗口迹卢。
隱藏的實際操作主要是去做了些清理操作,包括根據(jù)設定的removeFromSuperViewOnHide值來執(zhí)行是否從父視圖移除HUD窗口徒仓,以及執(zhí)行completionBlock操作腐碱,還有就是執(zhí)行代理的hudWasHidden:方法。這些操作是在私有方法-done里面執(zhí)行的掉弛,實現(xiàn)如下:
- (void)done {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
isFinished = YES;
self.alpha = 0.0f;
if (removeFromSuperViewOnHide) {
[self removeFromSuperview];
}
#if NS_BLOCKS_AVAILABLE
if (self.completionBlock) {
self.completionBlock();
self.completionBlock = NULL;
}
#endif
if ([delegate respondsToSelector:@selector(hudWasHidden:)]) {
[delegate performSelector:@selector(hudWasHidden:) withObject:self];
}
}
其它
MBProgressHUD的一些主要的代碼差不多已經(jīng)分析完了症见,最后還有些邊邊角角的地方,一起來看看殃饿。
顯示和隱藏的便捷方法
除了上面描述的實例方法之外谋作,MBProgressHUD還為我們提供了幾個便捷顯示和隱藏HUD窗口的方法,如下所示:
+ (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated
方法的簽名已經(jīng)很能說明問題了乎芳,在此不多描述遵蚜。
部分屬性值的設置
對于部分屬性(主要是”外觀”一節(jié)中針對菊花帖池、標題文本框和詳情文本框的幾個屬性值),為了在設置將這些屬性時修改對應視圖的屬性吭净,并沒有直接為每個屬性生成一個setter睡汹,而是通過KVO來監(jiān)聽這些屬性值的變化,再將這些值賦值給視圖的對應屬性寂殉,如下所示:
// 監(jiān)聽的屬性數(shù)組
- (NSArray *)observableKeypaths {
return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"labelColor", ..., nil];
}
// 注冊KVO
- (void)registerForKVO {
for (NSString *keyPath in [self observableKeypaths]) {
[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
} else {
[self updateUIForKeypath:keyPath];
}
}
- (void)updateUIForKeypath:(NSString *)keyPath {
if ([keyPath isEqualToString:@"mode"] || [keyPath isEqualToString:@"customView"] ||
[keyPath isEqualToString:@"activityIndicatorColor"]) {
[self updateIndicators];
} else if ([keyPath isEqualToString:@"labelText"]) {
label.text = self.labelText;
}
...
[self setNeedsLayout];
[self setNeedsDisplay];
}
代理
MBProgressHUD還為我們提供了一個代理MBProgressHUDDelegate囚巴,這個代理中只提供了一個方法,即:
- (void)hudWasHidden:(MBProgressHUD *)hud;
這個代理方法是在隱藏HUD窗口后調用不撑,如果此時我們需要在我們自己的實現(xiàn)中執(zhí)行某些操作文兢,則可以實現(xiàn)這個方法。
問題
MBProgressHUD為我們提供了一個HUD窗口的很好的實現(xiàn)焕檬,不過個人在使用過程中,覺得它給我們提供的交互功能太少澳泵。其代理只提供了一個-hudWasHidden:方法实愚,而且我們也無法通過點擊HUD來執(zhí)行一些操作。在現(xiàn)實的需求中兔辅,可能存在這種情況:比如一個網(wǎng)絡操作腊敲,在發(fā)送請求等待響應的過程中,我們會顯示一個HUD窗口以顯示一個loading框维苔。但如果我們想在等待響應的過程中碰辅,在當前視圖中取消這個網(wǎng)絡請求,就沒有相應的處理方式介时,MBProgressHUD沒有為我們提供這樣的交互操作没宾。當然這時候,我們可以根據(jù)自己的需求來修改源碼沸柔。
與SVProgressHUD的對比
與MBProgressHUD類似,SVProgressHUD類庫也為我們提供了在視圖中顯示一個HUD窗口的功能。兩者的基本思路是差不多的拗踢,差別更多的是在實現(xiàn)細節(jié)上烈评。相對于MBProgressHUD來說,SVProgressHUD的實現(xiàn)有以下幾點不同:
SVProgressHUD類對外提供的都是類方法工三,包括顯示迁酸、隱藏、和視圖屬性設置都是使用類方法來操作俭正。其內部實現(xiàn)為一個單例對象奸鬓,類方法實際是針對這個單例對象來操作的。
SVProgressHUD主要包含三部分:loading視圖段审、提示文本框和背景框全蝶,沒有詳情文本框闹蒜。
SVProgressHUD默認提供了正確、錯誤和信息三種狀態(tài)視圖(與loading視圖同一位置抑淫,根據(jù)需要來設置)绷落。當然MBProgressHUD中,也可以自定義視圖(customView)來顯示相應的狀態(tài)視圖始苇。
SVProgressHUD為我們提供了更多的交互操作砌烁,包括點擊事件、顯示事件及隱藏事件催式。不過這些都是通過通知的形式向外發(fā)送函喉,所以我們需要自己去監(jiān)聽這些事件。
SVProgressHUD中一些loading動畫是以Layer動畫的形式來實現(xiàn)的荣月。
SVProgressHUD的實現(xiàn)細節(jié)還未詳細去看管呵,有興趣的讀者可以去研究一下。這兩個HUD類庫各有優(yōu)點哺窄,大家在使用時捐下,可根據(jù)自己的需要和喜好來選擇。
小結
總體來說萌业,MBProgressHUD的代碼相對樸實坷襟,簡單易懂,沒有什么花哨難懂的東西生年。就技術點而言婴程,也沒有太多復雜的技術,都是我們常用的一些東西抱婉。就使用而言档叔,也是挺方便的,參考一下github上的使用指南就能很快上手授段。