若你的app需要懸停一個控件在絕大多數頁面上,那麼最後的解決方案是:把這個控件做成一個UIWindow,並且設置_statusWindow.windowLevel = UIWindowLevelStatusBar + 1;
。注意:這個控件是顯示在所有頁面中的,除非頁面掉用了它的隱藏函數([[PPPlayNoticeView currentNotice] animationHide];),不然它在app那個頁面都顯示。不過它依賴於app(app就是一個單進程應用,不可能存在多個進程。WKWebView是我見到的iOS唯一一個進程組件,不過通過它起的進程在iOS操作系統中,它雖然和app有通信機制,收到那個進程的數據,但是不受app管轄,app收到它的數據也可能是不實時的,像cookie數據),不會顯示在其它app頁面中,這個安卓是不一樣的。UIAlertView彈窗是系統級別的,可以不依賴於app存在,但是它出來後,不讓它消失什麼也幹不了。不是我們需要控件。
那新問題來了,若這個跨頁面的控件顯示時,你使用在keywindow上增加圖層,可能時增加到這個控件UIWindow的keywindow上。結果是你那個圖層顯示不出來,只看到一個帶透明度的圖層。那如何找到當前頁面的UIWindow呢?使用下面函數就能找到。
-(UIWindow *)getLevelNormalWindwow
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
UIViewController *result = nil;
UIView *frontView = [[tmpWin subviews] objectAtSafeIndex:0];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
result = nextResponder;
else
result = tmpWin.rootViewController;
NSArray *cv = [result childViewControllers];
NSLog(@"%@",cv);
if(cv && [cv isKindOfClass:[NSArray class]] && cv.count > 0)
{
return tmpWin;
}
}
}
return nil;
}
日誌打印:
2020-06-18 13:47:08.898734+0800 PinkPig[5900:133486] (
"<BITBaseTabBarController: 0x7fafb2e154e0>",
"<PPRoomViewController: 0x7fafb4816800>"
)
當然判斷if (tmpWin.windowLevel == UIWindowLevelNormal)
就夠了,下面多的if(cv && [cv isKindOfClass:[NSArray class]] && cv.count > 0)
只是以防萬一。你新建的UIWindow不會是UIWindowLevelNormal,不然不知道那個頁面在上面呢!,當然你建立rootViewController所在的window時,設置了非UIWindowLevelNormal的值那個判斷也要變成你設置成的windowLevel值(就是修改這句if (tmpWin.windowLevel == UIWindowLevelNormal)
),不設置windowLevel是默認值UIWindowLevelNormal。
一般是在AppDelegate裏設置UIWindow的,如:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:LoginVC];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
```。
當然我採用的組件化,是在系統模塊裏設置self.tabBarController的。
具體使用代碼:
[self addSubview:self.headDetailView];
當然你可以把這個函數放在靜態類或單例中,在那裏都能調用該函數,如在調用單例的該函數`[[[UIApplication sharedApplication] keyWindow] addSubview:self.headDetailView];`。