WKWebView 底部视图显示不全

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WKWebView 底部视图显示不全相关的知识,希望对你有一定的参考价值。

参考技术A 好早之前遇到的这个问题,用WKWebView 显示界面时,最底部的悬浮窗口少了不少像素。这是之前用UIWebView没有遇到过的。

这个问题只出现在ios10 , ios11应该是已经修复了。(反正我没有再遇到了)
先写解决方法,再说探求过程。
这个问题是导航栏导致的。也算是苹果的bug。将导航栏设置为不透明,问题直接就解决了。
self.navigationController.navigationBar.translucent = NO;
----------------------------------------------------------华丽的分割线----------------------------------------------
下面我们来调试下ios10下的WKWebview加载网页。底部悬浮窗是消失的。于是我打印了下偏移。

发现了么。offset的Y轴偏移量是-64。刚好是底部消失的距离。然后我猜测这个距离刚好和导航栏高度有关 (有些朋友消失20像素,我还没有研究,但是我感觉是跟状态栏有关)。
想起ios的排版方式,如果导航栏带透明。frame排版是从导航栏上开始的。如果不透明则在导航栏下面开始排布。所以猜测和透明度有关。事实证明。猜对了!!!
将导航栏设为不透明之后再打印。

界面也回归正常。
本来以为这个问题遇到的人不多。

实际显示视图时的 WKWebView 通知

【中文标题】实际显示视图时的 WKWebView 通知【英文标题】:WKWebView notification when view is actually shown 【发布时间】:2015-09-18 19:55:35 【问题描述】:

我想截取WKWebView 的屏幕截图。在 Web 视图完成加载后,我立即调用方法 drawViewHierarchyInRect(屏幕更新设置为 true)——为此,我观察了 Web 视图的 loading 属性。但是,我注意到,当 web 视图通知我加载完成时,它实际上并没有在屏幕上显示自己。这就是为什么屏幕截图总是只有白色的。当我在加载后 0.5 秒截取屏幕截图时(显然太长了),屏幕截图显示了所需的结果。我的问题是:我不知道网络视图何时实际显示在屏幕上,我可以将延迟设置为 0.05,但我不能 100% 确定它每次都能正常工作。因此,我的问题是:如何在实际显示 Web 视图并准备好截屏时通知我。

提前致谢!

顺便说一句:我正在使用 Swift 2.0 和 iOS 9 以及 Xcode 7(正式版本)

【问题讨论】:

【参考方案1】:

因为我刚刚在这方面工作,所以请告诉我我尝试了什么以及我是如何解决的。我尝试了几件事,首先,一个 WKUserScript

let webViewUserScript = WKUserScript(
        source: "window.onload = function()  webkit.messageHandlers.status.postMessage(\(wkwebView.hashValue)) ",
        injectionTime: WKUserScriptInjectionTime.AtDocumentEnd,
        forMainFrameOnly: true
    )

在“状态”命名空间上。这个理论上是等待所有内容加载完毕,然后调用WKScriptMessageHandler

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) 

通过以下方式注册时

wkwebView.configuration.userContentController.addScriptMessageHandler(self, name: "status")

我以为一切都准备好了。有时有效,但并非总是如此。

和你一样,我也尝试过添加 WKNavigationDelegate 并使用

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!)  

同样,这没有用。另外,为estimatedProgress 值添加一个观察者

wkwebView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)

然后尝试在

内制作屏幕截图
override func observeValueForKeyPath(keyPath: String?, ofObject: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)  

没用。

但是,有效的是定期检查 webView 的内容大小。我在由 WKUserScript 调用的 userContentController 函数中执行了此操作 - 但您也可以在 didFinishNavigation 函数中执行此操作,然后只需更改要再次调用的函数。代码如下:

let _contentSize = webview.scrollView.contentSize;

if (_contentSize.height == 0)          
  dispatch_after(createDispatchTime(0.01), dispatch_get_main_queue()) 
                self.userContentController(userContentController, didReceiveScriptMessage: message)
  
  return

这实质上是检查 contentSize 高度属性,如果它为零,它将每 0.01 秒再次调用该方法,直到设置该属性为止。这是我用于创建屏幕截图的函数

var view : UIView!

if self.useSnapShot 
   // Use the snapshot function
   view = webView.snapshotViewAfterScreenUpdates(true)

 else 
   // Draw the view as UIImage
   UIGraphicsBeginImageContextWithOptions(webView.frame.size, false, 0.0)
   webView.drawViewHierarchyInRect(webView.frame, afterScreenUpdates: true)
   let snapshot = UIGraphicsGetImageFromCurrentImageContext()
   view = UIImageView(image: snapshot)
   view.frame = webView.frame

我已经在设备和模拟器上对其进行了测试,并且可以正常工作。

编辑

这里是创建调度时间的函数

private func createDispatchTime(seconds: Double) -> dispatch_time_t
    let delay = seconds * Double(NSEC_PER_SEC)
    return dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

编辑#2

我创建了一个要点,它展示了我认为更好的方式 https://gist.github.com/christopherhelf/1640454bcace39a87c93#file-wkwebviewplus-swift

我替换了 webviews UIScrollview 的 setContentSize 函数,并通知父类发生了变化。

【讨论】:

我尝试了你的 swizzle 方法实现。甚至在 webView 实际呈现非常快的网页(如 Wikipedia)之前,它也会被触发 您还可以观察 contentSize 属性,而不是触发延迟函数或覆盖 setContentSize。这似乎适用于检测大小变化,但它似乎也可以在常规动画周期中触发,尽管没有变化。 这绝对是最好的答案之一。 iOS WebView didFinishLoad 在加载主要内容时调用,但 iOS WebKit 没有任何可靠的 Javascript 控件。问题就在这里。主要内容已加载,但一些 javascript 仍在工作(加载、重定向等)并且 WebKit 无法跟踪它。解决方案是控制 javascript Web 内容并在加载所有数据时调用脚本消息。我正在使用 [github.com/marcuswestin/WebViewJavascriptBridge] (WebViewJavascriptBridge)。 现在有一个 isLoading() 方法返回一个布尔值,您可以检查它而不是检查 contentsize 高度。 @peacer212 可以找到 avplayer 在 WKWebView 中显示的时间,如果有任何解决方案,请参见 ***.com/questions/55377677/…

以上是关于WKWebView 底部视图显示不全的主要内容,如果未能解决你的问题,请参考以下文章

AndroidConstraintLayout中RecyclerView 的底部数据显示不全以及覆盖其他View

AndroidConstraintLayout中RecyclerView 的底部数据显示不全以及覆盖其他View

华为手机显示不全怎么设置

复制图片然后粘贴到word中图片显示不全怎么办

se11字段显示不全

为啥word里的图片显示不全啊?