iOS獲取最上層window 顯示HUD彈窗 (解決iOS11不顯示的問題)

最近在封裝一個HUD彈窗,要獲取最上層可以顯示的window,所以研究了一下,發(fā)覺現(xiàn)在網(wǎng)上關于iOS11之后的變化,大家解釋的都不是很清楚,我這里說一下我的處理方法,也解釋一下原因。

之前大家獲取最上層window的方法:

let window = UIApplication.shared.windows.last!

這個方法iOS11之后,經(jīng)常會出現(xiàn)添加上去的視圖不顯示的問題,于是大家有的就用下面這個方法??:

let window = UIApplication.shared.keyWindow!

可是你要知道,這個方法拿到的是keyWindow,一般是我們在AppDelegate里面我們創(chuàng)建的用于顯示的window,很多情況下不是最上層的,比如有鍵盤正在輸入的時候,鍵盤的window是在keyWindow上層的,所以你添加的hud彈窗等會被鍵盤擋住!
我們來看一下鍵盤顯示的時候的window的層級關系:

image.png

image.png

  • UIWindow 這個就是我們自己創(chuàng)建顯示視圖的keyWindow
  • UITextEffectsWindow iOS8新增,鍵盤所在的window
  • UIRemoteKeyboardWindow iOS9新增,顯示鍵盤視圖的window
    我們可以看到鍵盤顯示的時候,iOS9之后UIApplication.shared.windows.last!是我們顯示鍵盤的UIRemoteKeyboardWindow,這個window會在鍵盤隱藏之后就銷毀,所以在鍵盤隱藏的瞬間,如果在上面添加視圖,就會閃一下,或者不顯示,就是因為這個window在鍵盤隱藏之后就移除銷毀了
    劃重點,我來說一種我遇到超級坑的情況:iOS11之后,如果你使用UIImagePickerController獲取相冊或者打開相機,系統(tǒng)也會自動創(chuàng)建一個UIRemoteKeyboardWindow,雖然這個window的isHidden等顯示屬性都是打開的,但是添加在上面的視圖就是不顯示,而且它一直霸占在windows的last位置還不釋放,所以就出現(xiàn)了你取last添加視圖,怎么也不顯示的情況了
    也就是說,當鍵盤顯示的時候,last的UIRemoteKeyboardWindow是可以添加我們的hud等視圖,并顯示出來,但是當鍵盤隱藏,last的UIRemoteKeyboardWindow是不可以做顯示的,我們看一下我獲取最上層可顯示window的方法:??
  func frontWindow() -> UIWindow? {
        
        for window in UIApplication.shared.windows.reversed() {
            
            guard window.screen == UIScreen.main else {
                continue
            }
            guard !window.isHidden && window.alpha > 0 else {
                continue
            }
            guard window.windowLevel >= .normal else {
                continue
            }
            guard !window.description.hasPrefix("<UIRemoteKeyboardWindow") || IQKeyboardManager.shared.keyboardShowing else {
                continue
            }
            return window
            
        }
        return nil
        
    }

我比較喜歡使用guard的語法糖,逆序遍歷windows,前面的三個判斷是排除了不作顯示的window,然后最后一個判斷就是如果是UIRemoteKeyboardWindow,在鍵盤不顯示的情況下,我們不使用它,繼續(xù)挑選它下層的window
IQKeyboardManager是我用來判斷當前鍵盤狀態(tài)的工具類(這個第三方很強大,兩句代碼就可以幫助你處理所有鍵盤遮擋輸入框的情況)
我這里是對鍵盤的window做了單獨判斷,來確保它可以顯示,如果你有其他的更方便的方法歡迎討論

這樣獲取到的window就可以讓我們的hud顯示在包括鍵盤在內(nèi)的最上層,不會被遮擋

歡迎更正錯誤和交流,回復評論和私信皆可 ??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容