ナビゲーションコントローラとテーブルビューの組み合わせ
2011年3月13日:iOS
ToDoリストやメモ帳のように、はじめにリストがあってそれから選択して編集するという構造は便利です。Table Viewも使用する必要があるので、少し複雑です。しかし、マスターするとアプリを作る際に役立つので、きちんと理解しておくといいでしょう。
プロジェクトの作成
Xcodeを起動して、「Create a new Xcode project」を選択します。
iOSのSingle View Applicationを選びます。
プロジェクト名を適当に記入し、言語を選択します。ここではSwiftを言語として使用します。
インターフェースの作成
Table Viewの設置と初期画面設定
ストーリボードでNavigation Controllerをドラッグ&ドロップで追加します。すると、Navigation ControllerとTable Viewの組み合わせが設置されます。
Table Viewをアプリ起動時に表示したいので、Navigation Controllerを選択します。そして、Attributeインスペクタの「Is Initial View Controller」を選択します。
これで、Table Viewがはじめに表示されるようになります。
Table Viewの設定
Table Viewの設定をします。タイトルがRoot View Controllerになっていますが、ダブルクリックにより「リスト」に変更します。次に、「Table View Cell」を選択して、Attributeインスペクタにより
- Style:Subtitle(リストにタイトルとサブタイトルが表示される)
- Identifier:Cell
- Accessory:Disclosure Indicator(「>」が表示される)
と設定します。
あとは、Table ViewとはじめからあったView Controllerへつなげます。「show」を選びます。
追加されたセグエを選択して、Identigierを「ShowPage」とします。
さらに、画面にラベル(Label)を設置し、選択したセルのタイトルとサブタイトルを表示できるようにします。
そして、ViewControllerにラベルのプロパティを追加します。NameはShowLabelとします。
UITableViewControllerの作成
TableViewを操作するためにUITableViewControllerを作成します。メニューにある
File->New->File…
によりCocoa Touchファイルを作成します。そして、Class名をListTableViewController、サブクラスをTableViewControllerとします。
作成したクラスとTable Viewを関連付けるために、ストーリボードでTable ViewのViewControllerを選択します。そして、クラスにListTableViewControllerを選択します。
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が実行されます。
実行結果
実行するとまずリストが現れて
セルを押すとタイトルとサブタイトルがラベルに表示されます。
著者:安井 真人(やすい まさと)
@yasui_masatoさんをフォロー