Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
未附加到视图层次结构时的WKWebKit javascript执行_Javascript_Ios_Angularjs_Webkit_Wkwebview - Fatal编程技术网

未附加到视图层次结构时的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)
    执行对服务器的请求
  • 服务器用JavaScript消息响应
    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
        }
    
    }