Note:首先相对于WebKit官网的代码,iOS上的版本使用WAKView代替了NSView。 比如Mac OS中将PlatformWidget定义为 NSView*, 而在iOS中则是WAKView *. 详细的内容可以参考Hursing的博客。
观察一份含有视频的页面的视图结构:
Hierarchy of UIWebView
<UIWebView: 0x8d8c160; frame = (0 78; 768 926);
| <_UIWebViewScrollView: 0x8d95310; frame = (0 0; 768 926);
| | <UIImageView: 0x8d96eb0; frame = (0 0; 10 10);
| | ...
| | <UIWebBrowserView: 0xa2a3c00; frame = (0 0; 768 926);
| | | <TileHostLayer: 0x8d8d4a0> (layer)
| | | | <TileLayer: 0x8a81e20> (layer)
| | | <CALayer: 0x7579a70> (layer)
| | | | <WebLayer: 0x71ab2b0> (layer)
| | | | | <WebLayer: 0x8ea80f0> (layer)
| | | | | | <WebLayer: 0x71848c0> (layer)
| | | | | | | <CALayer: 0x88a0650> (layer)
| | | | | | | | <FigPluginView: 0xb1d6670; frame = (0 0; 631 278);
| | <UIImageView: 0x8c650d0; frame = (0 919; 768 7);
| | <UIImageView: 0x8c7d760; frame = (761 0; 7 926);
Hierarchy of WebView
UIWebBrowserView (UIView)
| _webView <WebView: WAK: 0x7541e70 (WK: 0x7541ee0)>
| | <WebFrameView: WAK: 0x75428c0 (WK: 0x7542910)>
| | |<WAKScrollView: WAK: 0x7542c90 (WK: 0x7542cf0)>
| | | |<WAKClipView: WAK: 0x7542e80 (WK: 0x7542ed0)>
| | | | |<WebHTMLView:WAK: 0x8e226e0 (WK: 0x8e2c5a0)>
| | | | | |<UIWebPlugInView:WAK: 0x8e31a60 (WK: 0x8e31ad0)>
*这里不是直接的子视图的关系,而是由UIWebBrowserView的成员变量_webView所管理的一个WAKView树。
在从UIWebView向下展开,在视图层次上有播件的视图FigPluginView。下面的树是从WebView层展开会看到UIWebPlugInView(注意第二个大写的i)。而FigPluginView是由UIWebPluginView管理的(见前一篇)。
UIWebPluginView只关心plugin视图、layer和交互,所以通过下图可以看到它除了提供4个WebKit Plugin的接口函数,一些绘制操作的接口(setFrame,layout….), 剩下的基本都和layer有关了。Widget中的m_widget指向一个WAKView, 在WebFrameView创建WebHTMLView会将它指定给一个Widget。而Widget会由RenderWidget在加载插件时添加到FrameView上。
关于Widget可以参考这里:WebCore::Widget浅探。
这个创建过程是建立好插件视图FigPluginView、UIWebPlugInViiew和WebPluginController的关系。
UIWebPlugInView接收到setFrame来设置大小时会将插件视图FigPluginView添加到UIBrowserView中,然后将视频插件的layer关联进来。
在排版过程中,会通过RenderBox (Step 1)触发UIWebPlugInView attach插件视图。当视图移除时(Step 4)将插件的layer detach出去。
转载请注明出处: http://blog.csdn.net/horkychen