TableViewでデータを選択 -> 画面遷移 というケースがよく使われるとの事なので試してみました。
画面1 : tableViewでリストを表示 (DataTableViewController.swift / User List Scene)
画面2 : tableViewで選択されたデータを受け取り、画面遷移 (ViewController.swift / View Controller Scene)
画面1は新規に作成、画面2はプロジェクト作成時に生成されたものです。
NavigationControllerを配置して、画面遷移を実施します。
1. SingleViewでprojectを作成
2. Main.Storyboardを選択し、Navigation Controllerを最初からあるViewControllerの左にドラッグドロップ
Navigation ControllerとRoot View Controller (Table View)の繋がった箱がコピーされる
(最初のView Controller含めて3つの箱が表示されている)
3. ↑で追加したNavigation Controllerを選択し、右ペインのAttributes(右ペイン上部の"-↓-“みたいなアイコンを選択しておく)のViewControllerの項目にある”Is Initial View Controller”をチェックする
最初のViewControllerの左にあった矢印が消えて、追加したNavigation Controllerの左に矢印が追加される (= アプリが起動した時に最初に表示するシーンになるという意味)
4. (左2番目ペインの)Root View Controller Scene - Root View Controller - Root View Controllerを選択し、タイトルを書き換える
“***リスト”など (オブジェクトはRootViewController - Table Viewになっている)
5. ( 〃 )Root View Controller - Table View - Table View Cell を選択
1. 右ペインのStyleをSubtitle とする (title + subtitleの表示になる)
2. 〃 Identifer(一つ下にある)を”Cell”と入力する (Cellでアクセス出来る?)
3. 〃 Accosoryを"Dsiclosure Indicator”を選択する (画面遷移の”>”表示が出る)
segueで接続
6. (左2番目のペイン)TableView - Cell を選択した状態で、Cellをcontrol押しのIBAction接続で”最初からあった”Viewに接続する
この時にダイアログが表示されるので”Selection Segue - show”を選択する
テーブルViewコントローラから最初のViewに矢印がひかれる
7. ↑でひっぱったsegueを選択し、identiferを入力する
showCellDataとか…これは後ほどswiftコードの識別子として使用する
Table Viewのカスタムクラス(***.swift)を作成
8. TableViewControllerのカスタムクラスを作成する
1. File -> New -> FileでiOS-Sourceを選択、Cocoa Touch Classを選択し、Nextを押す
2. Class名をつける (DataTableViewControllerとか)、subClassを”UITableViewContoller”を選択してNext
3. 置き場所はdefault(ViewController.swiftなどが置かれている場所)でよい
9. ↑で作ったカスタムclassをview(今回はリスト)と関連づける
1. storyboardを選択し、TableViewを選択、(GUIの)上アイコン左(RootViewContlller)を選択
2. 右ペインの左から2番目のアイコン(propertyっぽいやつ)を選択してClassから”DataTableViewController”を選択する << ****.swiftのclass名を選択するという意味
10. カスタムクラスにTableViewに表示させるデータを記載する
DataTableTableViewController.swiftを選択
1. tableに表示されるリストを書く (class直下で良い)
// セルに表示するデータ
let modelList = [
(company: "aaa", model1: "a01", model2: "a02"),
(company: "bbb", model1: "b01", model2: "b02"),
(company: "ccc", model1: "c01", model2: "c02"),
(company: "ddd", model1: "d01", model2: "d02")
]
2. コメントアウトされているtableViewメソッドを有効化して、rawのデータを返すコードを記載する
// tableViewのセルに表示する部分
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
// 元からあるコードのCellの識別子を書き換える
// Configure the cell… // 以下の部分は手書きで記載
let cellData = modelList[indexPath.row]
// cellのプロパティに設定
cell.textLabel?.text = cellData.company
cell.detailTextLabel?.text = cellData.model1
return cell // ここは元のコードのまま
}
11. データを渡す部分を有効化して記載
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "showCellData” { // segueの識別子に合わせる事!
if let indexPath = self.tableView.indexPathForSelectedRow{
let modelData = modelList[indexPath.row]
(segue.destinationViewController as! ViewController).data = modelData
// 移動先にメンバ”data”を作る事(この時点で存在しない場合、メンバが無いerrorが出ている)
}
}
}
12. 受け渡しの個数、及びtable数を返している箇所を実装する
numberOfSectionsInTableView と tableView メソッドがreturn 0になっているので以下を返すように変更する
numberOfSectionsInTableView : return 1
tableView: return list.count
(これをやらないとtableに表示されない)
具体的には
// セクションの個数
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
// セクション内の行数
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
// return 0
return modelList.count
13. 表示するViewController.swift (tableViewから遷移される側)に渡されたデータを表示するコードを実装する
実際は、tableのデータを処理する部分。今回はサンプルなので、ラベルに渡されたデータを表示するだけのコードを記載
表示するViewControllerに、渡されたデータを表示するコードを記載する
// 渡されるデータを定義する (これが書かれていな買ったので、"12"ではエラーが出ていた)
var data:(company:String, model1:String, model2:String)?
// ラベルに接続するコード
func dispLabel(){
if let dispData = data {
Label1.text = dispData.company
Label2.text = dispData.model1
Label3.text = dispData.model2
}
}
@IBOutlet weak var Label1: UILabel!
@IBOutlet weak var Label2: UILabel!
@IBOutlet weak var Label3: UILabel!
(結構長いが...)とりあえず、上記実装で
- TableViewで選択したデータを、ViewControllerで表示
という動作が出来るようになりました。
注意点は
- 遷移先画面へのデータの受け渡しでは、受け側でデータを定義していないとエラーが出る(後で受け側に定義すれば出なくなる)
- TableViewの画面表示させるlistの定義と、仮実装・コメントされているスタブへの記述
Tableに適切なデータが表示されていない場合は、これが原因だったりしました
- swiftの記述で、identifierを参照するので、GUIに設定した内容を忘れないようにする
- DataTableViewController.swiftを生成するので、main.storyboardの画面にGUIで紐付けする
- NavigationControllerをGUIで配置したり、初期画面を設定したりするのを忘れない
辺りでしょうか
swiftのコードを記載します。
DataTableViewController.swift (DataTableViewControllerとして追加したクラス)
//
// DataTableTableViewController.swift
// TableView-Navigation01//
import UIKit
class DataTableTableViewController: UITableViewController {
// リストを追加
let modelList = [
(company: "aaa", model1: "a01", model2: "a02"),
(company: "bbb", model1: "b01", model2: "b02"),
(company: "ccc", model1: "c01", model2: "c02"),
(company: "ddd", model1: "d01", model2: "d02")
]
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 Incomplete implementation, return the number of sections
// return 0
return 1 // 変更
}
// セクション内の行数を返すコードに中身を変更する
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
// return 0
return modelList.count // 変更
}
// 元々コメントアウトされているコードを有効化して中に処理を書く
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) // param1をGUIで設定したIDに合わせる
// Configure the cell… // 以下の部分は手書きで記載
let cellData = modelList[indexPath.row]
// cellのプロパティに設定
cell.textLabel?.text = cellData.company
cell.detailTextLabel?.text = cellData.model1
// ここまで
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
// 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?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
// 以下のコードを記述する
if segue.identifier == "showCellData" {
// 行を取り出す
if let indexPath = self.tableView.indexPathForSelectedRow{
let modelData = modelList[indexPath.row] // 上で作ってある配列から行をインデックスとして取り出し
// (segue.destinationViewController as! ViewController).data = modelData
(segue.destinationViewController as! ViewController).data = modelData // 移動先にメンバ"data"を作る事
}
}
}
}
---
ViewController.swift (渡される側、そして元々あった画面に紐付けされている)
//
// ViewController.swift
// TableView-Navigation01
//
//
import UIKit
class ViewController: UIViewController {
// 渡す側のviewcontrollerから (segue.destinationViewController as! ViewController).dataとしてアクセスされる
var data:(company:String, model1:String, model2:String)? // 渡されるデータを定義する
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// 表示する関数を呼び出す
dispLabel()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 暫定表示UI (GUIからIBOutletで紐付け)
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!
// ボタン押下で遷移元に戻る
@IBAction func returnButtonClick(sender: AnyObject) {
_ = navigationController?.popViewControllerAnimated(true)
}
// ラベルに表示するコード
func dispLabel(){
if let dispData = data{
label1.text = dispData.company
label2.text = dispData.model1
label3.text = dispData.model2
}
}
}
0 件のコメント:
コメントを投稿