前幾天有一個完全透明的webView加載H5頁面的效果的實現,就相當於是一個半透明的遮罩層,上面有一個不透明的圖片,一般原生的帶遮罩層的彈框會采用這種方式,如果是原生代碼實現,就簡單的多了,視圖的疊加就可以搞定,但如果整個頁面包括遮罩層都要用webView加載H5來實現的話,就會有點兒復雜,這一效果還是花費了好一番功夫,在實際的開發過程中,發現了webView從未接觸過的奇妙的一面:_UIWebViewScrollView、UIWebBrowserView。
起初,是要設置webView的顏色和透明度(不是整體的alpha),但是發現無論怎么操作都不可以,中間的那部分區域也無法改變顏色;於是使用下面遞歸的方式輸出了WebView中所有繼承於UIView的子視圖;
func getNameSubViews(theView:UIView) { for view in theView.subviews { if view.isKindOfClass(UIView){ let name = NSString.init(UTF8String: object_getClassName(view)) print("WebView 的 子視圖 : \(name)") } getNameSubViews(view) } }
輸出結果:
WebView 的子視圖 : Optional(_UIWebViewScrollView)
WebView 的子視圖 : Optional(UIWebBrowserView)
結果就發現了兩個類:_UIWebViewScrollView、UIWebBrowserView;這是兩個從來沒見過的類,但是從名字也大致能看出來在什么位置;但是我很奇怪的是為什么沒有UIScrollView,或者還是這個_UIWebViewScrollView事實上和我們直接調用的webView.scrollView有着什么聯系,但是webView的scrollView屬性繼承於UIScrollView,UIScrollView繼承於UIView,中間的繼承關系中也並未出現_UIWebViewScrollView;這也是我疑惑的地方;然后我在for循環前面加上了這三行代碼,
let scroll:UIScrollView = UIScrollView() //UIView let name2 = NSString.init(UTF8String: object_getClassName(scroll)) print("UIScrollView取到的名稱 : \(name2)")
輸出結果:
UIScrollView取到的名稱 : Optional(UIScrollView)
輸出的是UIScrollView,這說明for循環中打印出來的_UIWebViewScrollView並不是webView中類型為UIScrollView的屬性scrollView中的,而是構成webView的一個子視圖;
接下來,為了搞明白他這兩個的圖層關系,我把遞歸方法做了一點兒改進;
func getNameSubViews(theView:UIView,index:Int) { print("\(index) 開始") for view in theView.subviews { if view.isKindOfClass(UIView){ let name = NSString.init(UTF8String: object_getClassName(view)) print("WebView 的 子視圖 : \(name)") } getNameSubViews(view,index: index+1) } print("\(index) 結束") }
輸出結果:
1 開始
WebView 的子視圖 : Optional(_UIWebViewScrollView)
2 開始
WebView 的子視圖 : Optional(UIWebBrowserView)
3 開始
3 結束
2 結束
1 結束
這個結果說明了UIWebBrowserView是在_UIWebViewScrollView上面的一個子視圖;如果傳入參數是webView.scrollView而不是webView,就會發現只有UIWebBrowserView輸出了,也就是說事實上UIWebBrowserView是webView的屬性scrollView上的一個子視圖,但事實上,我還是在疑惑為什么scrollView沒有輸出呢,這個留待之后深入研究了再進行解答吧;
其實還有一個辦法也可以清楚的看到圖層分布,運行如下代碼:
func changeColorSubViews(theView:UIView) { for view in theView.subviews { if view.isKindOfClass(UIView){ let name = NSString.init(UTF8String: object_getClassName(view)) if name == "_UIWebViewScrollView"{ view.backgroundColor = UIColor.redColor() print("WebView 的 紅色子視圖 : \(name)") }else if name == "UIWebBrowserView"{ view.backgroundColor = UIColor.greenColor() print("WebView 的 綠色子視圖 : \(name)") }else{ view.backgroundColor = UIColor.blueColor() print("WebView 的 藍色子視圖 : \(name)") } } changeColorSubViews(view) } }
運行出界面之后去Debug View Hierarchy里面就可以看到具體的圖層關系了;
這個關系理清楚之后就知道為什么設置不了webView的clearColor了,只要使用遞歸設置這兩個子視圖的背景色為clearColor,同時,設置
webView.opaque = false就OK了;當然,主要的一點還有加載的H5頁面也要直接使用div做成透明的,沒有背景body.
具體的webView深層次的架構體系,等周末研究研究再來總結。
