MBProgressHUD是Objective-C写的第三方库,用来作为进度指示器使用,原版Objective-C实现,当然,也有Swift实现,本文是依据原作者的Objective-C源码来分析的。
MBProgressHUD使用时本质是一个尺寸为屏幕尺寸(显示时能完全遮住其它视图)的UIView,而最好将它添加到窗口上或者窗口的根视图控制器的根视图上。
MBProgressHUD上主要由三个子视图:
- UILabel *label;—-HUD的标题
- UILabel *detailsLabel;——HUD的细节文本
- UIView *indicator;—–HUD的指示器
当然,这三个视图不一定会同时显示。MBProgressHUD有三个初始化方法(使用时是调用前两个方法,而前两个初始化方法内部是调用第三个方法):
- (id)initWithView:(UIView *)view {//方法中的view是HUD的直接父视图,一般是视图层次中最高的视图,比如窗口(窗口本身就是UIView)、窗口的根视图
NSAssert(view, @"View must not be nil.");
return [self initWithFrame:view.bounds];
}
- (id)initWithWindow:(UIWindow *)window
- (id)initWithFrame:(CGRect)frame //这里的frame是HUD直接父视图的frame,一般是窗口大小
设置了一些默认的属性,并且对子控件布局、逻辑进行了处理,子控件已添加到HUD上,只是没有设置其frame。
<1>[self setupLabels];
添加两个Label(label、detailsLabel,刚开始的frame都是HUD的frame)
<2>[self updateIndicators];
会对mode(指示器的模式:系统的UIActivityIndicatorView、环形指示器、条状指示器、没有指示器)进行判断,而mode属性的定义为(@property (assign) MBProgressHUDMode mode;)在指示器的位置(即同一位置)根据不同需求设置不同样式的指示器(即不同的view,要将原来的指示器移除[indicator removeFromSuperview];)
<3>[self registerForKVO];
利用KVO对HUD对象的某些属性进行值改变时的监听。
监听的对象属性有: [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"labelColor",
@"detailsLabelText", @"detailsLabelFont", @"detailsLabelColor", @"progress", @"activityIndicatorColor", nil];
}
<4>[self registerForNotifications];
利用NSNotification对状态条方向方式改变进行监听
MBProgressHUD并不只是中心显示的视图,它其实是占据了整个屏幕,在layoutSubviews方法中计算除了中心视图的尺寸、布局:
布局子视图方法(在这个方法中,计算出三个子控件的frame):
- (void)layoutSubviews
在计算时,indicator代表的是指示器,有三种,指示器的size都是固定的:
UIActivityIndicatorView:系统自带,默认size是{37,37}
MBBarProgressView:默认是(.0f, .0f, 120.0f, 20.0f)
MBRoundProgressView,默认是(0.f, 0.f, 37.f, 37.f)
totalSize:该方法根据HUD的具体样式计算出的frame,最后赋值给size,size就是中间的黑色区域
在drawRect方法中,系统对中心视图进行了绘制:
- (void)drawRect:(CGRect)rect
利用图形上下文绘制HUD,首先判断dimBackground是否为true来绘制dim背景,接着判断color是否为true来设置HUD的背景色
划出HUD的内容区域,根据计算出的frame