webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:
リクエストが常に であるというバグがあるようですが、通常のリンクと JavaScriptのリンクnil
の両方で機能する堅牢なソリューションがあります。target="_blank"
基本的に、私は別のエフェメラル WebView を使用して、新しいページの読み込みを処理します。Yoni Shalom に似ていますが、もう少しシンタックス シュガーがあります。
これを使用するには、まず WebView のデリゲート オブジェクトを設定します。この場合、自分自身をデリゲートとして設定します。
webView.UIDelegate = self;
次に、デリゲート メソッドを実装しwebView:createWebViewWithRequest:
、ブロック ベースの API を使用して、新しいページが読み込まれたときに何かを行います。この場合、外部ブラウザーでページを開いています。
-(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request {
return [GBWebViewExternalLinkHandler riggedWebViewWithLoadHandler:^(NSURL *url) {
[[NSWorkspace sharedWorkspace] openURL:url];
}];
}
それだけです。これが私のクラスのコードです。ヘッダ:
// GBWebViewExternalLinkHandler.h
// TabApp2
//
// Created by Luka Mirosevic on 13/03/2013.
// Copyright (c) 2013 Goonbee. All rights reserved.
//
#import <Foundation/Foundation.h>
@class WebView;
typedef void(^NewWindowCallback)(NSURL *url);
@interface GBWebViewExternalLinkHandler : NSObject
+(WebView *)riggedWebViewWithLoadHandler:(NewWindowCallback)handler;
@end
実装:
// GBWebViewExternalLinkHandler.m
// TabApp2
//
// Created by Luka Mirosevic on 13/03/2013.
// Copyright (c) 2013 Goonbee. All rights reserved.
//
#import "GBWebViewExternalLinkHandler.h"
#import <WebKit/WebKit.h>
@interface GBWebViewExternalLinkHandler ()
@property (strong, nonatomic) WebView *attachedWebView;
@property (strong, nonatomic) GBWebViewExternalLinkHandler *retainedSelf;
@property (copy, nonatomic) NewWindowCallback handler;
@end
@implementation GBWebViewExternalLinkHandler
-(id)init {
if (self = [super init]) {
//create a new webview with self as the policyDelegate, and keep a ref to it
self.attachedWebView = [WebView new];
self.attachedWebView.policyDelegate = self;
}
return self;
}
-(void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
//execute handler
if (self.handler) {
self.handler(actionInformation[WebActionOriginalURLKey]);
}
//our job is done so safe to unretain yourself
self.retainedSelf = nil;
}
+(WebView *)riggedWebViewWithLoadHandler:(NewWindowCallback)handler {
//create a new handler
GBWebViewExternalLinkHandler *newWindowHandler = [GBWebViewExternalLinkHandler new];
//store the block
newWindowHandler.handler = handler;
//retain yourself so that we persist until the webView:decidePolicyForNavigationAction:request:frame:decisionListener: method has been called
newWindowHandler.retainedSelf = newWindowHandler;
//return the attached webview
return newWindowHandler.attachedWebView;
}
@end
Apache 2 としてライセンスされています。