WKWebView
target="_blank"
HTMLタグに別名「新しいウィンドウで開く」属性を持つリンクは開きません<a href>
。
15 に答える
私の解決策は、ナビゲーションをキャンセルし、再度 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
}
最新バージョンの 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
}
自分自身をWKNavigationDelegateとして追加します
_webView.navigationDelegate = self;
デリゲート コールバックのdecisionPolicyForNavigationAction: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);
}
PS: このコードは私の小さなプロジェクトからのSTKWebKitViewController
もので、使用可能な UI を WKWebView にラップしています。
すでに WKWebView.navigationDelegate を設定している場合
WKWebView.navigationDelegate = 自己;
実装するだけです:
- (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 メソッドを実装する必要はありません。
Cloud xu
の答えは私の問題を解決します。
同等の Swift(4.x/5.0) バージョンが必要な場合は、次のとおりです。
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if let frame = navigationAction.targetFrame,
frame.isMainFrame {
return nil
}
// for _blank target or non-mainFrame target
webView.load(navigationAction.request)
return nil
}
もちろん、webView.uiDelegate
最初に設定する必要があります。