[swift]挫折しながら覚えるiOS開発その8 UIWebViewを使う


前回、TableViewのセクション分けができトップページはひと通りの機能ができました。

今回はリンクをクリックした際に、該当記事を表示する機能(詳細ページ)をUIWebViewを使って実装してみます。

WebViewに関しては↓の書籍に載っていたサンプルをベースに作成しました。

1. WebViewの実装

やったこととしては、まずLinkDetailViewController.swiftというファイル名で新しいViewControllerClassを追加しました。

swift8-2

続いて、Storyboardにも新たにViewControllerを追加し、ViewControllerのCustom Classを「LinkDetailViewController」にします。

その後、LinkDetailViewControllerにUIWebViewを追加して、AutoLayoutで「Add Missing Constraints」を実行します。

IBOutletでWebViewをコードに紐付けるのも忘れずにやっておきます。

そして、LinkDetailViewController.swiftでは、以下のようにlink変数を定義し、viewDidLoad内でlink.urlのページを開くという処理を追加しました。

# LinkDetailViewController.swift

import UIKit

class LinkDetailViewController: BaseViewController, UIWebViewDelegate {
    @IBOutlet weak var webView: UIWebView!

    var link: Link?

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.delegate = self

        if let link = self.link {
            initWithLink(link)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func initWithLink(link: Link) {
        self.loadRequest(link.url)
    }

    // MARK: - private
    func loadRequest(urlString: String) {
        let queryUrl = NSURL(string: urlString)
        let req = NSURLRequest(URL: queryUrl!)
        webView.loadRequest(req)
    }

    // 読み込み開始時に呼ばれる
    func webViewDidStartLoad(webView: UIWebView) {
        // ステータスバーのインジケーターを表示
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    // 読み込み完了時に呼ばれる
    func webViewDidFinishLoad(webView: UIWebView) {
        // インジケータを非表示にする
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }
}

ステータスバーのインジケーターというのは通信時にくるくるしているやつです。(下図参照)

swift8-1

2. Segueを使ったページ遷移

1.でWebViewの準備はできたのですが、現状だとそもそもページ遷移の記述を行っていないので、一覧ページから詳細ページに遷移することができません。

ページ遷移はSegue(セグエ, セグウェイ)と呼ばれる機能を使って作成します。

Segueの使い方に関してはドットインストールの動画を見ながら勉強しました。

#09 セグエで画面遷移させてみよう | iPhoneアプリ開発入門

Storyboardの操作はテキストだと説明が難しいですが、動画だと分かりやすいですね。

今回はLinkViewCellをクリックしたら詳細画面に遷移したいので、LinkViewCellにカーソルを合わせた状態でCtrlを押しながら、LinkDetailViewControllerに向かってドラッグします。

swift8-3-1

カーソルを離すと、どういう遷移にするかの画面が現れるので「show」を選択します。

swift8-4

Segueの設定が終わると、ViewController同士が結ばれます。

showを設定したので右から左に画面が遷移するアイコンが表示されています。

swift8-5

これでシミュレータを起動すると、一覧ページから詳細ページに遷移することができるようになりました。

ただし、画面は真っ白なままです。

3. パラメータを付与してページ遷移できるように

画面遷移はできるようになったものの、一覧ページから遷移する際に該当リンクの情報をパラメータとして詳細ページに渡していないため、LinkDetailViewControllerのlink変数がnilになってしまっています。

Segueでパラメータを渡せるようにするには遷移元のControllerのprepareForSegueメソッドをoverrideし、その中でパラメータ設定を行うのがよくあるやり方だそうです。

prepareForSegueメソッドの実装の前に、まずはSegueにIDをつけます。

Storyboard上のSegueを選択し、Attributes InspectorにあるStoryboard Segueの「Identifier」を選択します。

今回は「linkDetailSegue」と名前をつけました。

swift8-6

続いて遷移元となるViewController.swiftのprepareForSegueメソッドを実装します。

prepareForSegueはページ遷移すると呼ばれるメソッドであるため、identifierを元に処理を分けるようにしています。

# ViewController.swift

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "linkDetailSegue" {
            if let indexPath = self.tableView.indexPathForSelectedRow() {
                let link = linkList[indexPath.section][indexPath.row]
                var detailVC = segue.destinationViewController as! LinkDetailViewController
                detailVC.link = link
            }
        }
    }

indexPathForSelectedRowでどの位置のセルを選択したかが取れるので、indexPathを元にlinkListから該当linkを取得して、LinkDetailViewControllerのlink変数に設定します。

これでシミュレータを起動して、リンクをクリックするとWebView経由で詳細ページが表示されるようになりました。

と、ここまでつくって気づいたのですが、そういえば戻るボタンがどこにもありません。

完全に戻るボタンのことを忘れていました。。。

4. NavigationControllerを使う

戻るボタンをつくるにはどうすればいいか。

調べてみたところNavigationControllerを使うのがよさそうということが判明しました。

今回もドットインストールの講座で勉強して、NavigationControllerを実装していきます。

#11 NavigationControllerを使ってみよう | iPhoneアプリ開発入門

まずは、Storyboard上にNavigation Controllerを追加します。

Navigation Controllerを追加すると、左にNavigation Controller、右にサンプルのViewControllerがセットで追加されます。

右のViewControllerは不要なので削除します。

続いて、Navigation Controllerと一覧ページを紐付けるため、Navigation Controllerの左上にあるアイコンを右クリックします。

「root view controller」の右にある「+ボタン」を一覧ページまでドラッグします。

swift8-8

この状態でシミュレータを起動すれば画面上部にナビゲーションが追加されています。

詳細ページに行くと、戻るボタンが表示されています。

swift8-7

これでWebViewを使って該当リンクのページを表示するところまでできました。

次回は詳細ページをカスタマイズしてシェア機能やリロードボタンを追加したいと思います。

参考