WKWebView
からUIWebView
に切り替えたい。私のコードでは、Webビューインスタンスが(ビュー階層にアタッチせずに)オフスクリーンで作成され、URLがロードされます。ロードが完了すると、Webビューは別のUIWindow(インタースティシャル広告など)でユーザーに表示されます。 UIWebView
ですべてが正常に機能します。しかし、WKWebView
に切り替えた後、angular javascriptコードは予期しない方法で動作します。
いくつかの調査を行った後、WKWebView
インスタンスがビュー階層にアタッチされていない場合、javascriptタイマー(およびHTTPローダー)が一時停止されることがわかりました:デタッチされたWKWebView
で実行されるjavascriptでタイマーを開始すると、一時停止されませんWebビューがアタッチされるまで発生します。
誰かが可能な回避策を提案できますか(非表示のWebビューをキーウィンドウにアタッチしてから別のウィンドウに移動する以外に)?
問題(または、おそらくWebKit機能)を示すためのサンプルプロジェクトを作成しました
https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.Zip
テストアプリケーションは、タイマーをスケジュールしてHTTPリクエストをロードするjavascriptを含むWebページをロードします。スイッチを使用して、Webビューを表示/非表示にし(「hidden」プロパティを設定)、ビュー階層にアタッチ/デタッチできます。
Webビューがアタッチされている(非表示または表示されている)場合、Load
を押すと、JavaScriptは正常に機能します。success
またはfailure
アラートダイアログが表示されます。切り離されている場合、タイマーはビュー階層に接続されている場合にのみ起動します(「切り離し」を「オン」に切り替え、「ロード」を押し、数秒待ってから「オフ」に戻します)。 Safari WebInspectorからconsole.log
を確認することもできます。
テストWebページのソースは次のとおりです。
<!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>
そしてjavascript:
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;
};
}]);
同じ問題が発生したので、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
}
}
_
私の物語:
WKWebView(1)
を含むUINavigationController
がありますWKWebView(1)
には、_target: _blank
_パラメーターが設定されたハイパーリンクがありますWKUIDelegate
のwebView(_:didRequestNewWebView:)
をキャッチし、別のWKWebView(2)
をUINavigationController
にプッシュします。WKWebView(2)
はサーバーへのリクエストを実行しますWKWebView(1)
に応答しますWKWebView(1)
が停止しているため、メッセージが表示されません