WKWebView
WKWebViewはiOS8から新たに使用できるようになったWebViewで、WebKitFrameworkの中に含まれている。これまでのUIWebViewと比べると速くて高機能とのこと。使用方法は以下の通り。
WKWebViewの初期化
最初に初期化しておく。
private var webView = WKWebView()
各種設定
AutoLayout、Delegateなどの設定をviewDidLoad()で行う。デフォルトではジェスチャーが無効なので、有効にするためにはコードで明示する必要があることに注意が必要である。
override func viewDidLoad() {
// Autolayoutを設定
webView.translatesAutoresizingMaskIntoConstraints = false
// 親ViewにWKWebViewを追加
self.view.addSubview(webView)
// Delegateの設定
self.webView.UIDelegate = self
self.webView.navigationDelegate = self
// WKWebViewを最背面に移動
self.view.sendSubviewToBack(webView)
// レイアウトを設定(後述)
setWebViewLayoutWithConstant(0.0)
// ジェスチャーを許可
webView.allowsBackForwardNavigationGestures = true
// ページのロード
self.webView.loadRequest(NSURLRequest(URL: NSURL(string: url)!))
}
終了時
親ビューから削除する。Autolayoutの値もリセットされる。
override func viewDidDisappear(animated: Bool) {
webView.removeFromSuperview()
}
レイアウト設定
WKWebViewは、StoryBoard上で割り付けることが出来ない。他のパーツをStoryBoard上でAutolayout設定している場合は、Swift上でWKWebViewにAutolayout設定を行う。ConstraintはWebViewに対して指定するのではなく、親Viewに対して指定することに注意が必要である。
func setWebViewLayoutWithConstant(constant: CGFloat){
// Constraintsを一度削除する
for constraint in self.view.constraints {
let secondItem: WKWebView? = constraint.secondItem as? WKWebView
if secondItem == self.webView {
self.view.removeConstraint(constraint)
}
}
// Constraintsを追加
self.view.addConstraint(NSLayoutConstraint(item: self.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: webView, attribute: NSLayoutAttribute.Width, multiplier: 1.0, constant: 0.0))
self.view.addConstraint(NSLayoutConstraint(item: self.view, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: webView, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0.0))
self.view.addConstraint(NSLayoutConstraint(item: self.topLayoutGuide, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: webView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0.0))
self.view.addConstraint(NSLayoutConstraint(item: self.bottomLayoutGuide, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: webView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: constant))
}
以上により、ViewController上でWKWebViewを表示させることができる。goBack()やreload()はUIWebViewと同様に使用できる。
戻るボタンの実装
前のページに戻るためには、goForward()ではなぜかうまく動かなかった。以下のようにするとうまく動く。
let url = webView.backForwardList.forwardItem?.URL
webView.loadRequest(NSURLRequest(URL: url!))
プログレスビューの実装
ページ読み込みの進捗状況を表示するプログレスビューを表示することもできる。プログレスビュー自体のレイアウトや表示位置は、StoryBoard上で設定し、表示処理をSwiftで記述すると簡単である。
// プログレスビュー描画間隔
private let timerDur = 0.1
override func viewDidAppear(animated: Bool) {
// プログレスビューの描画
progressView.setProgress(0.0, animated: false)
progressView.hidden = false
timer = NSTimer.scheduledTimerWithTimeInterval(timerDur, target: self, selector: "updateProgressView", userInfo: nil, repeats: true)
}
override func viewDidDisappear(animated: Bool) {
if timer?.valid == true {
timer?.invalidate()
}
}
/**
プログレスビューを更新する
*/
func updateProgressView() {
progressView.setProgress(Float(webView.estimatedProgress), animated: true)
if webView.estimatedProgress == 1.0 && timer?.valid == true {
timer?.invalidate()
progressView.hidden = true
}
}
新規タブで開く
WKWebviewでURL読み込み時に任意の処理を実行したい場合には、decidePolicyForNavigationAction関数内に処理を記述する。新規タブで開く(target = _blank)の指定があった場合にデフォルトでは動作しないので、以下の記述が必要である。
if navigationAction.navigationType == WKNavigationType.LinkActivated{
if targetFrame == nil {
webView.loadRequest(NSURLRequest(URL: url))
}
}