我想在外部屏幕的webview中执行javascript。在我的主视图中,我尝试调用外部视图中的pop()
函数,如下所示:
let ex = ExternalDisplayViewController()
ex.pop(str: "Hello!")
当我运行它时,我得到"致命错误:在外部视图中的self.webView.evaluateJavaScript("go('\(str)')", completionHandler: nil)
处隐式展开可选值"时意外发现nil:
import UIKit
import WebKit
class ExternalDisplayViewController: UIViewController, WKUIDelegate {
private var webView: WKWebView!
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let config = WKWebViewConfiguration()
config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
config.setValue(true, forKey: "allowUniversalAccessFromFileURLs")
webView = WKWebView(frame: view.frame, configuration: config)
webView.scrollView.contentInsetAdjustmentBehavior = .never
webView.uiDelegate = self
// load local html file
let bundleURL = Bundle.main.resourceURL!.absoluteURL
let html = bundleURL.appendingPathComponent("external.html")
webView.loadFileURL(html, allowingReadAccessTo:bundleURL)
view.addSubview(webView)
}
func pop(str: String) {
self.webView.evaluateJavaScript("go('\(str)')", completionHandler: nil)
}
}
谢谢!
编辑(2023年3月1日):
抱歉,我是Swift新手,使用多个视图。如果我使用viewDidLoad()
或loadView()
,我会得到相同的结果:
import UIKit
import WebKit
class ExternalDisplayViewController: UIViewController, WKUIDelegate {
private var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
config.setValue(true, forKey: "allowUniversalAccessFromFileURLs")
webView = WKWebView(frame: view.frame, configuration: config)
webView.scrollView.contentInsetAdjustmentBehavior = .never
webView.uiDelegate = self
// load local html file
let bundleURL = Bundle.main.resourceURL!.absoluteURL
let html = bundleURL.appendingPathComponent("external.html")
webView.loadFileURL(html, allowingReadAccessTo:bundleURL)
view.addSubview(webView)
}
func pop(str: String) {
if (self.isViewLoaded) {
// viewController is visible
print("view controller should be visible")
self.webView.evaluateJavaScript("go('\(str)')", completionHandler: nil)
} else {
print("view controller is not loaded")
/*_ = self.view
self.webView.evaluateJavaScript("go('\(str)')", completionHandler: nil)*/
}
}
}
这将生成以下输出:
View Loaded?
view controller is not loaded
如何初始化此视图以使其可访问?
2条答案
按热度按时间qvtsj1bj1#
当你写这行字的时候
web视图将不会加载,您必须像这样将视图推送到navigationController
之后你可以调用ex.pop(string:“str”),但您必须在调用此函数之前给它一点时间,直到视图加载,因此您可以在ExternalDisplayViewController中的函数viewDidLoad的末尾添加以下内容
并且代替调用ex.pop(str:“Hello!”)改为编写以下代码
但是要确保在调用self时viewController有一个navigationController。navigationController
50few1ms2#
我想在外部屏幕的webview中执行javascript。
我不是很清楚你所说的外部屏幕是什么意思,所以我假设你想用
WKWebView
初始化UIViewController
,从你的包中加载external.html
,并执行一个javascript函数,而不显示视图控制器。(1)你应该保持对你的
ExternalDisplayViewController
的强引用,因为Swift的ARC可能会释放它。(2)
UIViewController
的生命周期函数,如viewDidLoad
和viewWillLayoutSubviews
,在其视图加载到视图层次结构之前不会被调用。您可以从here了解更多关于生命周期的信息。现在,在您的代码中,
ExternalDisplayViewController
中唯一要调用的函数是init
函数,因此您必须将WKWebView
初始化代码移到该函数中。(3)根据调用
pop
函数的位置和时间,你可能不能从webview调用你想要的javascript函数,因为在webview加载你的html和调用javascript函数之间会有一个竞态条件。你可以通过使用WKNavigationDelegate
'来防止这种情况的didFinish
委托函数,它会让你知道什么时候你的webview已经完成加载html。(4)您还可以考虑将
WKWebView
代码移到主视图控制器中,因为您不打算展示ExternalDisplayViewController
(假设我的假设是正确的)。