11 ответов:
мое решение-отменить навигацию и загрузить запрос с помощью loadRequest: снова. Это будет происходить аналогичное поведение, как UIWebView, который всегда открывает новое окно в текущем кадре.
сначала вам нужно иметь реализацию
WKUIDelegate. И установите его в_webview.UIDelegate. Затем реализовать:- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [webView loadRequest:navigationAction.request]; } return nil; }
ответ от @Cloud Xu является правильным ответом. Просто для справки, вот он в Swift:
// this handles target=_blank links by opening them in the same view func webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! { if navigationAction.targetFrame == nil { webView.loadRequest(navigationAction.request) } return nil }
добавить себя в качестве WKNavigationDelegate
_webView.navigationDelegate = self;и реализовать следующий код в делегат обратного вызова decidePolicyForNavigationAction:decisionHandler:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { //this is a 'new window action' (aka target="_blank") > open this URL externally. If we´re doing nothing here, WKWebView will also just do nothing. Maybe this will change in a later stage of the iOS 8 Beta if (!navigationAction.targetFrame) { NSURL *url = navigationAction.request.URL; UIApplication *app = [UIApplication sharedApplication]; if ([app canOpenURL:url]) { [app openURL:url]; } } decisionHandler(WKNavigationActionPolicyAllow); }P. S.: Этот код из моего маленького проекта
STKWebKitViewController, который обертывает удобный пользовательский интерфейс вокруг WKWebView.
чтобы использовать последнюю версию Swift 4.2+
import WebKitпродлить свой класс WKUIDelegate
установить делегат для webview
self.webView.uiDelegate = selfвыполнить способ протоколом
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil }
Если вы уже установили WKWebView.navigationDelegate
WKWebView.navigationDelegate = self;
вам просто нужно реализовать:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { BOOL shouldLoad = [self shouldStartLoadWithRequest:navigationAction.request]; // check the url if necessary if (shouldLoad && navigationAction.targetFrame == nil) { // WKWebView ignores links that open in new window [webView loadRequest:navigationAction.request]; } // always pass a policy to the decisionHandler decisionHandler(shouldLoad ? WKNavigationActionPolicyAllow : WKNavigationActionPolicyCancel); }таким образом, вам не нужно реализовывать метод WKUIDelegate.
Я подтверждаю, что Swift код Билла Вайнмана является правильным. Но нужно упомянуть, что вам также нужно делегировать UIDelegate для его работы, если вы новичок в разработке iOS, как я.
что-то вроде этого:
self.webView?.UIDelegate = selfИтак, есть три места, которые нужно внести изменения.
ни одно из этих решений не работало для меня, я решил проблему:
1) Реализация WKUIDelegate
@interface ViewController () <WKNavigationDelegate, WKUIDelegate>2) Установка делегата UIDelegate wkWebview
self.wkWebview.UIDelegate = self;3) реализации createWebViewWithConfiguration метод
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; [[UIApplication sharedApplication] openURL:[navigationAction.request URL]]; } return nil; }
вы также можете нажать другой контроллер вида или открыть новую вкладку и т. д.:
func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { var wv: WKWebView? if navigationAction.targetFrame == nil { if let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController { vc.url = navigationAction.request.URL vc.webConfig = configuration wv = vc.view as? WKWebView self.navigationController?.pushViewController(vc, animated: true) } } return wv }
я столкнулся с некоторыми проблемами, которые не могут быть решены только с помощью
webView.load(navigationAction.request). Поэтому я использую создать новый webView, чтобы сделать, и он просто отлично работает.//MARK:- WKUIDelegate func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { NSLog(#function) if navigationAction.targetFrame == nil { NSLog("=> Create a new webView") let webView = WKWebView(frame: self.view.bounds, configuration: configuration) webView.uiDelegate = self webView.navigationDelegate = self self.webView = webView return webView } return nil }
решение
подробности
xCode 9.2, Swift 4
полный образец с нажатием target=" _blank " links
import UIKit import WebKit class ViewController: UIViewController { var urlString = "http://google.com" var webView: WKWebView! fileprivate var webViewIsInited = false override func viewDidLoad() { super.viewDidLoad() } override func viewWillLayoutSubviews() { if !webViewIsInited { webViewIsInited = true if webView == nil { webView = WKWebView(frame: UIScreen.main.bounds, configuration: WKWebViewConfiguration()) } view.addSubview(webView) webView.navigationDelegate = self webView.uiDelegate = self webView.loadUrl(string: urlString) } } } extension ViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { decisionHandler(.allow) } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { if let host = webView.url?.host { self.navigationItem.title = host } } } extension ViewController: WKUIDelegate { func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if navigationAction.targetFrame == nil { let vc = ViewController() vc.urlString = navigationAction.request.url?.absoluteString ?? "http://google.com" vc.view.frame = UIScreen.main.bounds vc.webView = WKWebView(frame: UIScreen.main.bounds, configuration: configuration) navigationController?.pushViewController(vc, animated: false) return vc.webView } return nil } } extension WKWebView { func loadUrl(string: String) { if let url = URL(string: string) { if self.url?.host == url.host { self.reload() } else { load(URLRequest(url: url)) } } } }
Это сработало для меня:
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { WKWebView *newWebview = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration]; newWebview.UIDelegate = self; newWebview.navigationDelegate = self; [newWebview loadRequest:navigationAction.request]; self.view = newWebview; return newWebview; } return nil; } - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { decisionHandler(WKNavigationActionPolicyAllow); } - (void)webViewDidClose:(WKWebView *)webView { self.view = self.webView; }как вы можете видеть, то, что мы делаем здесь, просто открывает новый
webViewС Новым url-адресом и контролем возможности закрытия, просто если вам нужен ответ от этогоsecond webviewбудет отображаться на первом.

Comments