programing

뷰 계층에 연결되지 않은 경우 WKWebKit javascript 실행

lovejava 2023. 3. 10. 20:58

뷰 계층에 연결되지 않은 경우 WKWebKit javascript 실행

전환하고 싶다WKWebView부터UIWebView제 코드로 웹 뷰 인스턴스는 (뷰 계층에 접속하지 않고) 오프스크린으로 생성되어 URL이 로드됩니다.로딩이 완료되면 웹 뷰는 별도의 UI Indow(인터스티셜 광고 등)로 사용자에게 표시됩니다.모든 것이 정상적으로 동작합니다.UIWebView; 로 전환한 후WKWebView각도 javascript 코드가 예기치 않게 동작합니다.

몇 가지 조사를 한 결과, 자바스크립트 타이머(및 HTTP 로더)가 일시 정지되어 있는 것을 알게 되었습니다.WKWebViewinstance는 뷰 계층에 연결되어 있지 않습니다: 분리된 상태에서 실행되는 javascript에서 타이머를 시작하면WKWebView- 웹 뷰가 연결될 때까지 실행되지 않습니다.

가능한 회피책을 제안할 수 있습니까(숨겨진 웹 뷰를 키 창에 연결한 후 다른 창으로 이동하는 것 제외)?

문제(또는 WebKit 기능)를 설명하기 위한 샘플 프로젝트를 만들었습니다.

https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip

테스트 어플리케이션은 타이머를 스케줄하여 HTTP 요청을 로드하는 javascript가 포함된 웹 페이지를 로드합니다.스위치를 사용하여 웹 보기를 표시/숨기고('숨김' 속성을 설정) 보기 계층에서 연결/분리할 수 있습니다.

iOS 8.0에서 실행되는 샘플 앱

웹 보기가 연결되어 있고(숨겨지거나 표시됨)Loadjavascript는 정상적으로 동작합니다.success또는failure[ Alert ]대화상자분리된 경우 - 타이머는 뷰 계층에 연결된 경우에만 실행됩니다('분리'에서 '온'으로 전환, '로드'를 누른 후 몇 초간 기다렸다가 다시 '오프'로 전환).확인하실 수도 있습니다.console.logSafari Web Inspector에서 확인할 수 있습니다.

테스트용 웹 페이지 소스를 다음에 나타냅니다.

<!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>

자바스크립트:

angular.
  module('project', []).
  controller('MyController', ['$scope','notify', function ($scope, notify) {
  $scope.callNotify = function(msg) {
    notify(msg);
  };
}]).
  factory('notify', ['$window', '$http', '$q', '$timeout', function(win, $http, $q, $timeout) {
  return function(msg) {
    deferred = $q.defer();

    $timeout(function() {
      $http.get('http://jsonplaceholder.typicode.com/posts').
      success(function(data, status, headers, config) {
        alert("success");
        console.log("success")
      }).
        error(function(data, status, headers, config) {
        alert("error");
        console.log("error")
      });
    });
    return deferred.promise;
  };
}]);

같은 문제에 부딪혀 WK Web View를 뷰 계층에 추가하여 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
    }

}

제 이야기:

  1. 는 나나 a a a가 있다UINavigationControllerWKWebView(1)
  2. WKWebView(1).target: _blank 세트(')
  3. 후, 는 「 」 「 」 「 」 「 」WKUIDelegate의 »webView(_:didRequestNewWebView:) 한 번 밀다WKWebView(2)UINavigationController
  4. WKWebView(2)에 대한 요청을 합니다.
  5. 합니다.WKWebView(1)
  6. 수 , 「 」는, 「 」는 「 」는 「 」입니다.WKWebView(1)

언급URL : https://stackoverflow.com/questions/31169884/wkwebkit-javascript-execution-when-not-attached-to-a-view-hierarchy