本篇博文记录MBProgressHUD源码学习过程,从官方提供的Demo项目入手,一步步了解其代码结构,学习它使用的技术,体会作者的编程思想。
一、结构
我们先来看下MBProgressHUD的结构,查看其类的定义。
1.MBProgressHUD是UIView的子类。
2.属性:
1.
//代理,<MBProgressHUDDelegate>仅定义了一个方法:- (void)hudWasHidden:(MBProgressHUD *)hud;用于执行HUD隐藏之后的操作
@property (weak, nonatomic) id<MBProgressHUDDelegate> delegate;
//执行HUD隐藏之后的操作的Block,目的同上
@property (copy, nullable) MBProgressHUDCompletionBlock completionBlock;
2.
//延迟时间,若任务在graceTime到时之前就完成了,HUD不再展示,即防止为短时间任务显示HUD
@property (assign, nonatomic) NSTimeInterval graceTime;
//最短展示时间,防止HUD隐藏的过快
@property (assign, nonatomic) NSTimeInterval minShowTime;
//配置HUD是否隐藏之后就从其superview上移除。默认NO
@property (assign, nonatomic) BOOL removeFromSuperViewOnHide;
3.
//指定进度条的样式,包括菊花、圆饼、环形、水平进度条、自定义样式和纯文本等
@property (assign, nonatomic) MBProgressHUDMode mode;
//内容(label+indicator+customView)颜色
@property (strong, nonatomic, nullable) UIColor *contentColor;
//显示和隐藏时的动画类型:Fade(淡入淡出)、Zoom(放大显示缩小隐藏)、ZoomIn、ZoomOut
@property (assign, nonatomic) MBProgressHUDAnimation animationType;
//内容框(bezelView)距离中心位置的偏移,例如CGPointMake(0.f, MBProgressMaxOffset),内容框会在底部居中
@property (assign, nonatomic) CGPoint offset;
@property (assign, nonatomic) CGFloat margin;//各元素到HUD的边距
@property (assign, nonatomic) CGSize minSize;//内容框的最小尺寸
@property (assign, nonatomic, getter = isSquare) BOOL square;//强制HUD为方形
@property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled;//内容框(bezelView)是否受设备加速计的影响,默认YES
4.
@property (assign, nonatomic) float progress;//进度
@property (strong, nonatomic, nullable) NSProgress *progressObject;//进度对象,用于更新进度条
5.
//内容框,即展示实际内容(文本、indicator)的矩形框
@property (strong, nonatomic, readonly) MBBackgroundView *bezelView;
//背景试图,会覆盖整个屏幕
@property (strong, nonatomic, readonly) MBBackgroundView *backgroundView;
//自定义视图用于展示
@property (strong, nonatomic, nullable) UIView *customView;
@property (strong, nonatomic, readonly) UILabel *label;//文本
@property (strong, nonatomic, readonly) UILabel *detailsLabel;//文本下面的详细文本
@property (strong, nonatomic, readonly) UIButton *button;//文本下面的action button
3.其他相关类
(1) MBBackgroundView
- UIView的子类,在MBPRogressHUD中充当内容框(bezelView)和背景视图(backgroundView)两种角色。
- 提供两种样式:清晰样式(MBProgressHUDBackgroundStyleSolidColor)和模糊样式(MBProgressHUDBackgroundStyleBlur)
- 模糊样式是通过
UIVisualEffectView
和UIBlurEffect
实现的。
(2) MBRoundProgressView
- UIView的子类,展示为饼状/环形的进度条。
(3) MBBarProgressView
- UIView的子类,展示为条状的进度条。
(4) MBProgressHUDRoundedButton
- UIButton的子类,展示位圆角button,作为HUD上的功能按钮。
知识点:HUD中有个button属性如下:
/**
* A button that is placed below the labels. Visible only if a target / action is added.
*/
@property (strong, nonatomic, readonly) UIButton *button;
注意它的注释Visible only if a target / action is added
。也就是说,只有给button添加事件之后,该按钮才会展示出来。这是如何做到的呢?那就是重写UIView的函数- (CGSize)intrinsicContentSize
:
- (CGSize)intrinsicContentSize {
// Only show if we have associated control events
if (self.allControlEvents == 0) return CGSizeZero;
CGSize size = [super intrinsicContentSize];
// Add some side padding
size.width += 20.f;
return size;
}
这个函数用来设置控件的内置尺寸。可以看到,通过判断allControlEvents
的个数来判断button上是否有事件,如果有事件,就在原来内置的尺寸上加20。
二、代码追踪
了解了MBProgressHUD的基本结构之后,接下来我们就看看具体的功能是如何实现的。HUDDemo提供了15