ナビゲーションコントローラとテーブルビューの組み合わせ

ノート

 ToDoリストやメモ帳のように、はじめにリストがあってそれから選択して編集するという構造は便利です。Table Viewも使用する必要があるので、少し複雑です。しかし、マスターするとアプリを作る際に役立つので、きちんと理解しておくといいでしょう。

プロジェクトの作成

 Xcodeを起動して、「Create a new Xcode project」を選択します。

createnewproject

iOSのSingle View Applicationを選びます。

singleview

プロジェクト名を適当に記入し、言語を選択します。ここではSwiftを言語として使用します。

3

インターフェースの作成

Table Viewの設置と初期画面設定

 ストーリボードでNavigation Controllerをドラッグ&ドロップで追加します。すると、Navigation ControllerとTable Viewの組み合わせが設置されます。

setting

Table Viewをアプリ起動時に表示したいので、Navigation Controllerを選択します。そして、Attributeインスペクタの「Is Initial View Controller」を選択します。

set

これで、Table Viewがはじめに表示されるようになります。

Table Viewの設定

 Table Viewの設定をします。タイトルがRoot View Controllerになっていますが、ダブルクリックにより「リスト」に変更します。次に、「Table View Cell」を選択して、Attributeインスペクタにより

  1. Style:Subtitle(リストにタイトルとサブタイトルが表示される)
  2. Identifier:Cell
  3. Accessory:Disclosure Indicator(「>」が表示される)

と設定します。

viewcell

あとは、Table ViewとはじめからあったView Controllerへつなげます。「show」を選びます。

drag

追加されたセグエを選択して、Identigierを「ShowPage」とします。

show

さらに、画面にラベル(Label)を設置し、選択したセルのタイトルとサブタイトルを表示できるようにします。

label

そして、ViewControllerにラベルのプロパティを追加します。NameはShowLabelとします。

スクリーンショット 2015-03-08 23.19.15

UITableViewControllerの作成

 TableViewを操作するためにUITableViewControllerを作成します。メニューにある

File->New->File…

によりCocoa Touchファイルを作成します。そして、Class名をListTableViewController、サブクラスをTableViewControllerとします。

list

 作成したクラスとTable Viewを関連付けるために、ストーリボードでTable ViewのViewControllerを選択します。そして、クラスにListTableViewControllerを選択します。

list

ListTableViewControllerのコーディング

 まず、ListTableViewController.swiftを以下のようにコーディングします。

import UIKit

struct ListData{
    var title:String
    var sub_title:String
}

class ListTableViewController: UITableViewController {

    let List:[ListData]
    
    required init(coder aDecoder:NSCoder){
        List=[]
        List.append(ListData(title:"タイトル1", sub_title:"サブタイトル1"))
        List.append(ListData(title:"タイトル2", sub_title:"サブタイトル2"))
        super.init(coder:aDecoder)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return List.count
    }

    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let data=List[indexPath.row] as ListData
        cell.textLabel?.text=data.title
        cell.detailTextLabel?.text=data.sub_title
        return cell
    }
    
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier=="ShowPage" {
            if let indexPath=self.tableView.indexPathForSelectedRow(){
                let data=List[indexPath.row] as ListData
                (segue.destinationViewController as ViewController).detailItem = data
            }
        }
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }

}

以上のことを順に説明します。

渡すデータの構造体を宣言

 データをセグエを通して渡す際に構造体を使います。構造体を以下のように定義します。

struct ListData{
    var title:String
    var sub_title:String
}

リストのデータ配列の作成

 initで作成した構造体の配列Listを作ります。

    let List:[ListData]
    
    required init(coder aDecoder:NSCoder){
        List=[]
        List.append(ListData(title:"タイトル1", sub_title:"サブタイトル1"))
        List.append(ListData(title:"タイトル2", sub_title:"サブタイトル2"))
        super.init(coder:aDecoder)
    }

セクションとセルの数を指定

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

でセクションの数を指定します。今回はセクションは1つなので1を返します。

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return List.count
    }

でセルの数を返します。セルの数は作成した配列Listの大きさです。

セルに表示させる

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let data=List[indexPath.row] as ListData
        cell.textLabel?.text=data.title
        cell.detailTextLabel?.text=data.sub_title
        return cell
    }

でセルに表示させる内容を設定します。cell.textLabel?.textがタイトルで、cell.detailTextLabel?.textがサブタイトルです。

セグエへ送る

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier=="ShowPage" {
            if let indexPath=self.tableView.indexPathForSelectedRow(){
                let data=List[indexPath.row] as ListData
                (segue.destinationViewController as ViewController).detailItem = data
            }
        }
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }

でセグエへ情報を送ります。後で設定するViewControllerのdetailItemに押されたセルの情報を送ります。

ViewControllerのコーディング

 続いてViewController.swiftのコーディングを行います。以下のようにコーディングします。

import UIKit

class ViewController: UIViewController {

    @IBOutlet var ShowLabel: UILabel!
    
    var detailItem: ListData?{
        didSet{
            self.Show()
        }
    }
    
    func Show(){
        if let data:ListData = self.detailItem {
            if let show = self.ShowLabel {
                ShowLabel.text=data.title+","+data.sub_title
            }
            
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        Show()
    }

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


}

まず、

    var detailItem: ListData?{
        didSet{
            self.Show()
        }
    }
    
    func Show(){
        if let data:ListData = self.detailItem {
            if let show = self.ShowLabel {
                ShowLabel.text=data.title+","+data.sub_title
            }
            
        }
    }

でプロパティがセットされると実行されます。その結果、Showが実行されます。そして、

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        Show()
    }

でビューが読み込まれたらShowが実行されます。

実行結果

実行するとまずリストが現れて

gamen1

セルを押すとタイトルとサブタイトルがラベルに表示されます。

gamen2

著者:安井 真人(やすい まさと)