未附加到视图层次结构时的WKWebKit javascript执行
我想从未附加到视图层次结构时的WKWebKit javascript执行,javascript,ios,angularjs,webkit,wkwebview,Javascript,Ios,Angularjs,Webkit,Wkwebview,我想从UIWebView切换到WKWebView。在我的代码中,web视图实例是在屏幕外创建的(不附加到视图层次结构),并且加载URL。加载完成后,web视图将在一个单独的UIWindow(如间隙广告)中呈现给用户。使用UIWebView时一切正常;但是在切换到WKWebView之后,角度javascript代码的行为方式出乎意料 在做了一些研究之后,我发现当WKWebView实例未连接到视图层次结构时,javascript计时器(和HTTP加载器)会被挂起:如果在javascript中启动一个
UIWebView
切换到WKWebView
。在我的代码中,web视图实例是在屏幕外创建的(不附加到视图层次结构),并且加载URL。加载完成后,web视图将在一个单独的UIWindow(如间隙广告)中呈现给用户。使用UIWebView时一切正常
;但是在切换到WKWebView
之后,角度javascript代码的行为方式出乎意料
在做了一些研究之后,我发现当WKWebView
实例未连接到视图层次结构时,javascript计时器(和HTTP加载器)会被挂起:如果在javascript中启动一个在分离的WKWebView
中运行的计时器,则在连接web视图之前不会触发它
有人能提出一个可能的解决方法吗(除了将隐藏的web视图附加到关键窗口,然后将其移动到另一个窗口之外)
我创建了一个示例项目来演示这个问题(或者更可能是WebKit特性)
测试应用程序加载一个带有javascript的网页,javascript调度计时器并加载HTTP请求。可以使用开关显示/隐藏web视图(设置“隐藏”属性)并将其从视图层次结构中附着/分离
如果web视图被附加(隐藏或可见),并且您点击了Load
,javascript工作正常:您可以看到success
或failure
警报对话框。如果已分离-计时器仅在连接到视图层次结构时才会启动(将“分离”切换为“打开”,点击“加载”,等待几秒钟,然后切换回“关闭”)。您还可以从Safari Web Inspector检查console.log
以下是测试网页来源:
<!doctype html>
<html ng-app="project">
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="project.js"></script>
</head>
<body>
<div id="simple" ng-controller="MyController" data-ng-init="callNotify(message);">
</div>
</body>
</html>
遇到同样的问题后,除了将WKWebView添加到视图层次结构并使用AutoLayout将其移到屏幕外,我从未找到任何解决方案。幸运的是,此解决方案确实能可靠地工作。我遇到了完全相同的问题,并已使用
UIStackView
解决了它。我创建了StackNavigationController
,这是对UINavigationController
的最小替换,它基本上向堆栈添加了新视图,同时隐藏了除最后一个视图之外的所有视图。因此,所有视图仍处于层次结构中,执行和加载,但只有最后一个视图可见。没有动画,很多缺少的API,可以随意构建
public class StackNavigationController: UIViewController {
private(set) var viewControllers: [UIViewController] = []
private var stackView: UIStackView { return view as! UIStackView }
override public func loadView() {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fillEqually
view = stackView
}
func pushViewController(_ viewController: UIViewController, animated: Bool) {
let previousView = stackView.arrangedSubviews.last
viewControllers.append(viewController)
stackView.addArrangedSubview(viewController.view)
previousView?.isHidden = true
}
func popToRootViewController(animated: Bool) {
while stackView.arrangedSubviews.count > 1 {
stackView.arrangedSubviews.last?.removeFromSuperview()
viewControllers.removeLast()
}
stackView.arrangedSubviews.first?.isHidden = false
}
}
我的故事:
UINavigationController
,其中WKWebView(1)
作为根视图WKWebView(1)
有一个带有target:\u blank
参数集的超链接WKUIDelegate
的webView(uquot:didRequestNewWebView:)
并将另一个WKWebView(2)
推到UINavigationController
WKWebView(2)
执行对服务器的请求WKWebView(1)
WKWebView(1)
已暂停你有没有找到解决这个问题的办法?我们最近也遇到了同样的问题。我最终将这个视图添加到层次结构中,并使其不可见。我也做了同样的事情,似乎这是目前“最好”的解决方案。我是在想象什么,还是iOS文档以前做得更好?@AlexLementuev愿意将此作为一个答案吗?我也可以使用零矩形网络视图。
public class StackNavigationController: UIViewController {
private(set) var viewControllers: [UIViewController] = []
private var stackView: UIStackView { return view as! UIStackView }
override public func loadView() {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fillEqually
view = stackView
}
func pushViewController(_ viewController: UIViewController, animated: Bool) {
let previousView = stackView.arrangedSubviews.last
viewControllers.append(viewController)
stackView.addArrangedSubview(viewController.view)
previousView?.isHidden = true
}
func popToRootViewController(animated: Bool) {
while stackView.arrangedSubviews.count > 1 {
stackView.arrangedSubviews.last?.removeFromSuperview()
viewControllers.removeLast()
}
stackView.arrangedSubviews.first?.isHidden = false
}
}