UITableView と UINavigationController を使った基本的な画面遷移

ここでは、ナビゲーションコントローラとテーブル・ビューを組み合わせます。

テーブルビュー内のエントリー (行) をタップしたら、その内容を表示するビューに移動します。 移動先では画面左上のナビゲーションエリアに「戻る」ボタンが表示されており、それをタップすると元のテーブルに戻ります。

Master-Detail とは違うの?

いわゆる、Master-Detail の構成と似ていますが違います。Master-Detail では、スプリット・ビュー・コントローラとナビゲーションコントローラが組み合わせれて使われていて、大きな画面でテーブル部分とビューがサイドバイサイドで表示されます。

さっそく、こうした画面遷移を実装してみましょう。

プロジェクトを Single View App テンプレートで作成します。 メインのストーリーボードを開き、ビューを Navigation Controller に埋め込みます。

ひとつめのビューには Table View を一つ配置します。また、これのアウトレットを tableView: UITableView! とします。

@IBOutlet weak var tableView: UITableView!

次にもうひとつ View Controller をオブジェクトライブラリからドラッグアンドドロップます。画面上にはラベルを一つ配置しておきます。

ひとつめのビューコントローラから、新しく追加したビューコントローラに Show セグウェイを設定します。

そして、このセグウェイに showDetailSegue という識別子を設定します。

Swift ファイルを DetailViewController.swift という名前で作成します。

ここでは UIViewController から派生した、DetailViewController という名前のクラスを定義します。 そして、DetailViewController を二つ目のビューコントローラのクラスに割り当てます。

ラベルのアウトレットを label1 として作成します。

また、テーブルビュー側から渡される値でラベルを初期化するコードを追加し、 DetailViewController.swift は次のようになります。

import UIKit

class DetailViewController: UIViewController {
    var text = ""
    @IBOutlet weak var label1: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = text
    }    
}

さて、テーブル側のコードに戻りましょう。

テーブル (UITableView) を使うには、UITableViewDataSource と UITableViewDelegate をコンフォームします。

テーブル (UITableView) の使い方については「表組みビューやリストを管理 〜 UITableView」をみてください。

先に出来上がりのコードを示します。

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    let data: [String] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
    let cellIdentifier = "UITableViewCell"

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
        tableView.dataSource = self
        tableView.delegate = self
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetailSegue" {
            if let row = tableView.indexPathForSelectedRow?.row {
                let vc = segue.destination as! DetailViewController
                vc.text = data[row]
            }
        }
    }
    
    // MARK: - UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
        let text = data[indexPath.row]
        
        cell.textLabel!.text = text
        return cell
    }
    
    // MARK: - UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "showDetailSegue", sender: nil)
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

このうち、テーブル内の行をタップして、次の画面に遷移する箇所は次の performSegue の箇所です。

    // MARK: - UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "showDetailSegue", sender: nil)
        ...
    }

このセグウェイでナビゲーションコントローラのナビゲーションスタックに、DetailViewController をプッシュします。

以上で、目標としていた画面遷移が実現できるはずです。

ここでは、テーブルビューとナビゲーションコントローラを使って、表組みリストから詳細画面に移動して、そこから戻るという動作を実現する方法について説明しました。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Swift による iOS 開発入門