iOS -- 透明H5(webView)效果的实现
前几天有一个完全透明的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深层次的架构体系,等周末研究研究再来总结。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 为DeepSeek添加本地知识库
· .NET程序员AI开发基座:Microsoft.Extensions.AI
· 精选4款基于.NET开源、功能强大的通讯调试工具
· 数据不出内网:基于Ollama+OneAPI构建企业专属DeepSeek智能中台
· 大模型工具KTransformer的安装