我有一个UWiew,它有一个WKWebView作为子视图。 Web视图显示正确,但显示HTML文档需要很长时间(超过一秒)。该文档是一个本地文件(项目中的HTML文件),因此没有Internet延迟,它是一个相对简单的HTML文档。 HTML文档上有八个小图像,但是另一个没有任何图像的HTML文档存在类似的问题。
以下是将HTML文档加载到Web视图中的代码:
override func viewDidLoad() {
super.viewDidLoad()
let localHtmlFile = Bundle.main.url(forResource: "place", withExtension: "html");
let request = URLRequest(url: localHtmlFile!);
webView.load(request);
}
我正在使用Xcode 9.3,Swift 4.1和iOS 11.2。
每次进入该屏幕时都会发生延迟。如果第一次无法阻止延迟,是否可以保持网络视图,以便延迟只发生一次?
答案 0 :(得分:2)
显然,延迟是由创建WKWebView
的新实例所花费的时间引起的,而不是加载HTML文档所需的时间。为了避免这种延迟,我想出了一种重用Web视图的方法。
首先,我从故事板场景中删除了Web视图,这样每次加载视图时都不会创建新的Web视图。我创建了一个名为container
的通用视图,其大小与我想要的Web视图大小相同。
然后我创建了一个静态变量来保持指向Web视图的指针:
static var webView: WKWebView? = nil
在我的例子中,这个静态变量位于一个名为GameController
的类中。
接下来我更改了代码以检查静态webView
变量是否为零。如果webView
为nil,则代码会创建一个新的Web视图,并将静态变量设置为指向该Web视图。然后,代码以编程方式将Web视图添加为故事板场景中容器视图的子视图。
要设置故事板并编写此代码,我使用了以下网站上的说明:
http://www.onebigfunction.com/ios/2016/12/14/iOS-javascript-communication/
使用Web视图(我的代码中为WebViewController
)的场景的视图控制器中的基本代码如下所示:
override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
webView = WKWebView(frame: webFrame,
configuration: config)
GameController.webView = webView
} else {
webView = GameController.webView
}
self.container!.addSubview(webView)
}
在我的情况下,我想将Web视图中的JavaScript代码信息发送到我的应用程序中的Swift代码,因此我必须更多地使用配置。我还希望Web视图是透明的,所以我添加了一个声明来做到这一点。
override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "scriptHandler")
webView = WKWebView(frame: webFrame,
configuration: config)
webView.isOpaque = false
GameController.webView = webView
} else {
webView = GameController.webView
webView.configuration.userContentController.removeScriptMessageHandler(
forName: "scriptHandler")
webView.configuration.userContentController.add(self,
name: "scriptHandler")
}
self.container!.addSubview(webView)
}
最初我只是在第一次创建Web视图时设置了脚本处理程序,但这并不起作用。显然每次加载场景时都会生成一个新的视图控制器对象,因此旧的脚本处理程序不起作用。此代码删除指向旧视图控制器的脚本处理程序,并添加指向新视图控制器的脚本处理程序。
答案 1 :(得分:0)
只需保留对ViewController的引用,可能是在父控制器,应用程序委托,甚至单例/全局中。在后续加载时它应该更快一些。