この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
WKWebViewのリンクをPeek、Pop時の挙動がカスタマイズできるようになった
iOS 9まではWWKWebView
のallowsLinkPreview
プロパティでプレビューをするかしないかの制御ができるくらいで、リンクをPeekした時はプレビュー表示、Pop時にはSafariアプリでリンク先ページを開くという挙動をカスタマイズすることはできませんでしたが、iOS 10でカスタマイズできるようになりました。
カスタマイズで何ができるようになったのか
具体的には以下ができるようになりました。
- リンクのURLに応じてプレビューするかしないかを制御できるようになった
- peek時(プレビュー時)に表示する画面(UIViewController)が指定できるようになった
- pop時のイベントがハンドリングできるようになった
上記はWKUIDelegate
に追加された下記メソッドを実装することで可能となります。
optional public func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool
optional public func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController?
optional public func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)
リンクのURLに応じてプレビューするかしないかを制御するには
public func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool
を実装します。
パラメータのWKPreviewElementInfo
はiOS 10で追加されたクラスでlinkURL
プロパティ(リンク先のURL)を持ちます。
以下はリンク先URLがhttps://classmethod.jp/
の時のみプレビューする実装となります。
public func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool {
return elementInfo.linkURL?.absoluteString == "https://classmethod.jp/"
}
peek時(プレビュー時)に表示する画面(UIViewController)が指定するには
public func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController?
を実装します。
任意のUIViewController
を返すことができます。また、defaultActions
にはプレビュー時に上にスワイプした際に表示されるアクションのデフォルトが渡ってきます。デフォルトを使う場合もカスタムのアクションにする場合も、いずれにしても返すUIViewController
のpreviewActionItems
を実装すればそれが表示されます。
以下ではstoryboardからIDを指定して生成したUIViewController
を返しています。
public func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController? {
let vc = storyboard?.instantiateViewController(withIdentifier: "PreviewingViewController")
return vc
}
pop時のイベントがハンドリングするには
public func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)
を実装します。
リファレンスにはYou must display the previewed view controller inside of your app.
と書かれていますので、パラメータで渡されたUIViewController
を表示しましょう。
public func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController) {
present(previewingViewController, animated: true)
}
PreviewingViewControllerの実装サンプル
PreviewingViewControllerは以下のような実装としました。
pop時に当該ViewControllerが表示された後に閉じるボタンと、previewActionItems
でプレビュー時に上にスワイプした際に表示されるアクションを定義しています。(※ここでは、指定したアイテムの表示確認が目的であるため、タップ時の動作やアイテム名に特に意味はありません。)
class PreviewingViewController: UIViewController {
@IBAction func didTapCloseButton(_ sender: AnyObject) {
dismiss(animated: true)
}
override var previewActionItems: [UIPreviewActionItem] {
get {
let item1 = UIPreviewAction(title: "アイテム1", style: .default) { (_, _) in }
let item2 = UIPreviewAction(title: "アイテム2", style: .destructive) { (_, _) in }
let item3 = UIPreviewAction(title: "アイテム3", style: .selected) { (_, _) in }
return [item1, item2, item3]
}
}
}
実行結果
まとめ
今回はWKWebViewのLink Preview APIについてご紹介しました。
これまでpop時にはSafariが起動していましたが、アプリ内で完結することが可能となりました。
カスタマイズできることが増えることは何よりです。