前言
我們有時(shí)候會(huì)遇到需要顯示加載框,統(tǒng)一封裝的時(shí)候,有時(shí)候調(diào)用會(huì)給它一個(gè) view 用作父視圖,如果沒有父視圖,要考慮把它加載在什么上面。
例如獲取當(dāng)前顯示的 UIViewController 還是使用 window。獲取當(dāng)前的 UIViewController 的話可能會(huì)遇到添加該加載框后,view 又添加了其他 view 覆蓋住加載框。所以還是使用 window ,項(xiàng)目中使用 window 遇到添加 view 后未顯示。解決筆記如下。
UIWindow的獲取方式有四種
1. 某個(gè) view 所在的 window:
如果是 UIViewController 的 View ,有時(shí)候 window 為 null ,原因是 view 沒有完全加載完成或者在 ViewDidload 中才剛剛加載完,view 的 window 屬性無(wú)法被獲?。?。
UIWindow *window = self.view.window;
2. keyWindow
可以添加 view 并顯示出來(lái)的(有可能獲取到是 nil)。
獲取應(yīng)用程序的主窗口,用來(lái)接收鍵盤以及非觸摸類的消息事件的 UIWindow ,而且程序中每個(gè)時(shí)刻只能有一個(gè) UIWindow 是 keyWindow 。
提示:如果某個(gè) UIWindow 內(nèi)部的文本框不能輸入文字,可能是因?yàn)檫@個(gè) UIWindow 不是 keyWindow 。
UIWindow *window = [UIApplication sharedApplication].keyWindow;
3. delegate
這個(gè) window 添加的 view 很有可能被控制器的 view 覆蓋而顯示不了。
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
keyWindow 與 delegate 中的 window 其實(shí)是一樣的,keyWindow 的存在的意義,其實(shí)就是為了說(shuō)明當(dāng)前的 window 接管了這個(gè)控制器的view而已,你可以在 keyWindow 上加載你自己的建立的 view 了。
4. windows
獲取當(dāng)前頂層的窗口。
UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
keyWindow 即便獲取到不是 nil,有時(shí)候也會(huì)有其它 window 覆蓋在上面,導(dǎo)致添加上去的 view 不會(huì)顯示。所以使用第該方式 windows 獲取。
例如:在銷售 APP 中遇到的 keyWindow 獲取成功,但是上面還有一個(gè) UITextEffectsWindow 覆蓋了 keyWindow 添加的 加載框。
但是要注意,移除加載框的時(shí)候,因?yàn)?windows 中的數(shù)據(jù)是變化的,所以移除的時(shí)候要遍歷 windows 中 window 查找,移除加載框。
代碼如下:
@implementation MBProgressHUD (EHIProgressHUD)
#pragma mark - 顯示加載框
+ (MBProgressHUD *)ehi_showLoadViewWithMessage:(NSString *)message {
return [self ehi_showLoadViewWithMessage:message toView:nil];
}
+ (MBProgressHUD *)ehi_showLoadViewWithMessage:(NSString *)message toView:(UIView *)view {
[self ehi_hideHUD];
if (view == nil) {
view = [[[UIApplication sharedApplication] windows] lastObject];
view.tag = EHITEMPVIEW_TAG;
}
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
hud.label.text = message;
return hud;
}
#pragma mark - 移除加載框
+ (void)ehi_hideHUD {
[self ehi_hideHUDForView:nil];
}
+ (void)ehi_hideHUDForView:(UIView *)view {
if (view == nil) {
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
view = [window viewWithTag:EHITEMPVIEW_TAG];
if (view) {
[self hideHUDForView:view animated:YES];
}
}
}
參考
iOS UIWindow:獲取屏幕最上層的窗口(這篇文章有一點(diǎn)說(shuō)的不對(duì),keywindow不是隨時(shí)獲取的到的)
keyWindow與delegate中Window的區(qū)別
(說(shuō)明了keywindow不是隨時(shí)獲取的到的)