MBProgressHUD 使用遇到的问题
问题背景: 整理 HUD 扩展的复用模块时,遇到了 MB 遮盖导航栏的问题。但是使用 initWithFrame: 构造器并不能很好的解决问题。
之前暴露导航栏的写法(个人):
+ (void) chExShowTip:(NSString *)tip toVc:(UIViewController *)vc {
CH_MAIN_BLOCK(^{
MBProgressHUD *hud = [MBProgressHUD new];
[vc.view addSubview:hud];
hud.mode = MBProgressHUDModeCustomView;
if (tip) {
hud.label.text = tip;
}
if (vc.edgesForExtendedLayout == 0) {
hud.offset = CGPointMake(0, -32);
}
hud.margin = 10;
hud.bezelView.style = MBProgressHUDBackgroundStyleBlur;
hud.bezelView.backgroundColor = [UIColor clearColor];
hud.removeFromSuperViewOnHide = YES;
[hud showAnimated:YES];
[hud hideAnimated:YES afterDelay:2];
});
}
后果: 总感觉有点麻烦。
仔细察看 MB.h 之后的写法:
这种写法诞生的理由:
/**
* Displays a simple HUD window containing a progress indicator and two optional labels for short messages.
*
* This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.
* The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all
* user input on this region, thereby preventing the user operations on components below the view.
*
* @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO.
* @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread.
*/
从上可以看出: 有两种方法不会"遮挡"导航栏[1. 使用 initWithFrame: 初始化 HUD | 2. 设置 userInteractionEnabled = NO ,但是这样毫无意义]。所以诞生了以下写法:
+ (void) chExShowHUDWithMsg:(NSString *)message {
CH_MAIN_BLOCK(^{
MBProgressHUD *hud = [[MBProgressHUD alloc] initWithFrame:CGRectMake(0, 64, CH_SCREEN_WIDTH, CH_SCREEN_HEIGHT - 64)];
[[self lastWindow] addSubview:hud];
hud.mode = MBProgressHUDModeIndeterminate;
hud.label.text = message;
hud.margin = kHudMagin.integerValue;
hud.bezelView.style = MBProgressHUDBackgroundStyleBlur;
hud.bezelView.backgroundColor = [UIColor redColor];
hud.removeFromSuperViewOnHide = YES;
hud.offset = CGPointMake(0, -32);
[hud showAnimated:YES];
});
}
但是,我悲剧的发现不对。当我使用 initWithFrame: 初始化之后(frame : (0,64,width,height-64))。添加到 window 之后(frame : (0,32,width,height))。那就看看源码问题出在哪里,后来发现 HUD 又被设置了一次 bounds 。源代码如下:
- (void)updateForCurrentOrientationAnimated:(BOOL)animated {
// Stay in sync with the superview in any case
if (self.superview) {
self.bounds = self.superview.bounds;
}
......
}
所以:
不管怎样, HUD 的 bounds.size 永远都会和 superView 相等。设置 bounds 不会改变 center , frame 是由 bounds 和 center 动态计算的。所以为了保证 center 不变,height 增加了 64 ,那么动态计算的 frame.y 就会向上移动 64/2。
那么就得出了一个偏方:
将初始化的 frame 变为 (0,128,width,hieght-128),那么最后得出的实际 frame 就为(0,64,width,height)了,但是这样无法确保 tabBar 响应了。