WKWebView、色々ハマる。
WKWebView、はまった・・・
元々、UIWebView で作っていたのに、どう言う訳か deprecated となり、変わって WKWebView 使えと。
MKWevView ね、色々便利というか高度なわけよ。一番驚いたのが、日付の文字列を解釈して、カレンダーアプリに渡しちゃうところね。お客さんに指摘されてびっくりこいたよ。余計なことすんなよ、と。あとはまったのが、target = "_blank" でリンクしてると開かないわけよ。長押しすると反応するんだけどね。言い分はわかるよ。わざわざ別ウインドウ指定してるんだから、同一ページに表示する手はないよね、ってことなんだけど、長押しに気づかないわな、ふつう。
ってことで、WKWebView で target = "_blank" しているときに、同一ページでリンクする方法、日付を解釈してカレンダーが起動しないようにする方法について忘れないように記載しておこう。
WKWebView で target = "_blank" しているときに、同一ページでリンク先を開く方法
delegate method で指定が必要。具体的には、以下のように記述。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURL* url = navigationAction.request.URL;
// target = _blank でリンクできるように対応
switch ( navigationAction.navigationType )
{
case WKNavigationTypeLinkActivated:
// <a href="hoge" target="_blank"> の対応
if ( !navigationAction.targetFrame
|| !navigationAction.targetFrame.isMainFrame )
{
[_webView loadRequest:[NSURLRequest requestWithURL:url]];
decisionHandler( WKNavigationActionPolicyCancel );
return;
}
break;
default:
break;
}
decisionHandler( WKNavigationActionPolicyAllow );
}
要は、main frame 以外を指定されたら、強制的に webView で表示しろ、という記述。めんどくさいんだよ、WKWebView。
次に、日付をタッチすると自動的にカレンダーが起動してしまうの回避策。
WKUserContentController* userContentController = [[WKUserContentController alloc] init];
WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
configuration.dataDetectorTypes = WKDataDetectorTypeNone;
configuration.userContentController = userContentController;
_webView = [[WKWebView alloc] initWithFrame: self.view.bounds configuration: configuration];
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
[self.view addSubview:_webView];
これもね、マジめんどくさいのよ。そもそも、webView の configuration を設定したいわけなんだけど、肝心の configuration を設定する method が限られているので、すごい遠回りした設定になってしまう訳だ。初めから、configuration を read write property にすればいいのに、なぜか、read only property なんだよこれ。
という訳で、やり方わかったからいいけど、出来上がるまでにかなり時間を要したので冷や汗かいちゃったぞ。
Swift 記述だけど、以下のサイトはかなり参考になる。