※以前に記載したTableView、Segue、データの保存方法を使用するため、もし前記事をご覧になられていない方は、下記をご参照ください。
3-1. TableViewを使ってみよう
3-2. Segueを使ってみよう
3-3. データを保存してみよう
今回のToDoListの目標は、下図のようにToDoアイテムの追加、リスト表示、削除、更新ができることを目指します。また、アプリを落としてもデータが保存されている(データが消えない)ように設定もします。
アプリの見た目(Main.storyboard)の設定
では、アプリの見た目を作成するために、Main.storyboardを設定していきます。まず始めに、プロジェクトを作成します。Xcodeを開いて、
Create a new Xcode project → Single View Application → product name を”ToDoList”としてCreateボタン
を押します。プロジェクトが作成されましたら、Main.storyboadを開きます。
まずは、ToDoアイテムを表示するリスト画面を作成するために、View ControllerにTableView及びNavigationBarを配置します。
ユーティリティエリアよりTableViewを選択し、View Controllerにドラッグ&ドロップします。合わせて、セルを一つ追加(Prototype Cellsを"1"に)しておきます。
次に、追加したセルを選択し、Identifierを"cell"とします。
最後に、TableViewをControlを押しながら、View Controllerへドラッグ&ドロップし、"dataSource"と"delegate"をチェックしましょう。これでTableViewの使用が可能になります。
※この辺りの詳細は、「3-1. TableViewを使ってみよう」にて解説しています。
次に、NavigationBarの設定です。ユーティリティエリアよりNavigationBarをViewControllerへドラッグ&ドロップし、追加したNavigationBarにBarButtonItemをドラッグ&ドロップします。合わせてBarButtonItemのSystem Itemを"Add"に変更し、追加を表す”+”マークに変更しておきましょう。
以上で、ToDoリストを表示する画面の設定は完了です。
次に、アイテムを追加する画面を設定していきます。ユーティリティエリアよりViewControllerをドラッグ&ドロップし、ViewController(画面)を追加します。合わせて、画面サイズも変更しておきましょう。
では、追加したViewControllerに下図のようにNavigationBar、BarButtonItem(戻る)、TextField、Buttonを作成しましょう。
以上で、アイテムを追加する画面の作成は完了です。
では、見た目(Main.storyboard)の設定の最後にSegueを設定します。ToDoList画面の"+"を押下するとアイテム追加画面へ、アイテム追加画面の戻るを押下するとToDoList画面へ遷移するよう設定します。
"+"ボタンをControlを押しながらアイテム追加画面へドラッグ&ドロップし、Showを選択します。
同様に、"戻る"ボタンをControlを押しながらToDoList画面へドラッグ&ドロップし、Showを選択します。下図のように表示されていれば成功です。
ここで、一旦ビルドして画面がちゃんと表示されていること、画面遷移できることを確認します。そこまで出来れば、画面の設定は完了です。次はソースコードを記述(実装)していきます。
ToDoアイテム追加画面の実装
まず初めに、ToDoListへアイテムを追加する画面の実装を行います。この画面では、
・テキストフィールドに入力された文字列をAddボタンが押下されたら保存する
・保存するにあたっては、NSUserDefaultsを使用
・キーボード以外をタッチするとキーボードが下がる
・キーボードのreturnを押下すると、キーボードが下がる
という機能を実装します。
まずは、ソースコードを記述するSwiftファイルを作成します。
File→New→File...を選択し、CocoaTouchClassを選択します。
Nextボタンを押し、
Class:AddToDo
Subclass of:UiIViewController
Language:Swift
を選択し、Nextボタンを押します。
そうするとAddToDo.swiftというファイルができると思います。
次に、これをMain.storyboardで作成したViewから使用できる設定をします。
Main.stoyboadを開いて、アイテムを追加する画面の左上のボタンを選択肢、Custom ClassにAddToDoと記述します。こうすることにより、このViewとAddToDo.swiftが関連付けられたことになります。
次に、テキストフィールドに入力された文字列をAddボタンが押下されたら保存する機能を実装します。
出来上がったAddToDo.swiftにMain.storyboadから変数を追加します。
テキストフィールドをcontrolを押しながらソースコードの画面にドラッグ&ドロップし、Connectionがoutletになっていることを確認し、適当に名前をつけます(例では、itemTextとしています)。次に、Addボタンも同様にcontrolを押しながらソースコードの画面にドラッグ&ドロップし、ConnectionをActionに変更し適用に名前をつけます(例では、addItemとしています)。
変数の準備ができたら、import UIKit直下に
var todoItem = [String]()
と記述します。これは、ToDoアイテムを一旦保存するためのString型の配列で、クラス(ファイル)を跨って使用するため、 classの前(import UIKit直下)に記載します。
次に、ボタンをクリックされた際にNSUserDefaultsにテキストフィールドの値を保存するよう記述します。テキストフィールドの値をString型の配列todoItemに格納し、NSUserDefaultsにSetします。合わせて、テキストフィールド内の文字列は、空欄にします。
@IBAction func addItem(sender: AnyObject) { todoItem.append(itemText.text!) itemText.text = "" NSUserDefaults.standardUserDefaults().setObject(todoItem, forKey: "todoList") }
次に、キーボード以外をタッチするとキーボードが下がる機能です。class AddToDo: UIViewController 内に以下を記述します。これは、決まり文句みたいなものです。
override func touchesBegan(touches: Set, withEvent event: UIEvent?) { self.view.endEditing(true) }
最後に、キーボードのreturnを押下すると、キーボードが下がる機能です。class AddToDo: UIViewController 内に以下を記述します。こちらも決まり文句みたいなものです。
func textFieldShouldReturn(textField: UITextField!) -> Bool { itemText.resignFirstResponder() return true }
これで、アイテムを追加する画面の実装は完了です。次にToDoList画面を実装していきます。
ToDoList画面の実装
次に、追加したToDoアイテムのリストを表示する画面を実装していきます。この画面では、
・NSUserDefaultsに保存されているアイテムの取得、表示
・NSUserDefaultsに保存されているアイテムをスライドして削除
・テーブル(リスト)を下に引っ張って更新
する機能を実装したいと思います。
NSUserDefaultsに保存されているアイテムの取得、表示機能を実装します。
この実装は、3-1. TableViewを使ってみように記載した通りの実装をします。詳細は、3-1をご参照ください。
まず初めにTableViewを取得するために、class名の後ろにUITableViewDelegateを追加します。
class ViewController: UIViewController,UITableViewDelegate {
次に、NSUserDefaultsの値を取得し、先ほどのAddToDo.swiftにて作成した配列型の変数todoItemに代入します。これは起動時に呼ばれる関数であるviewDidLoad()内に記述します。
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if NSUserDefaults.standardUserDefaults().objectForKey("todoList") != nil { todoItem = NSUserDefaults.standardUserDefaults().objectForKey("todoList") as! [String] } }
次に、以下二つの関数を記述します。
一つ目は、Tableに表示する行数を指定する関数です。これは、先ほど記述したNSUserDefaultsの値が代入されている変数todoItemが保持している文字列の数をカウントします。
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return todoItem.count }
2つ目は各行へ値を表示する関数です。NSUserDefaultsの値が代入されている変数todoItemが保持している文字列を各テーブルに表示していきます。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cellValue = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell") cellValue .textLabel?.text = todoItem[indexPath.row] return cellValue }
次に、NSUserDefaultsに保存されているアイテムをスライドして削除機能を記述します。まず初めに、TableViewを操作するためにMain.storyboadから変数を持ってきます。
TableViewをcontrolを押しながらソースコードの画面にドラッグ&ドロップし、Connectionがoutletになっていることを確認し、適当に名前をつけます(例では、todolistTableとしています)
次に、下記の関数を記述します。これはTableViewのcellをEdit(編集)したい場合に使用する関数です。今回は削除(delete)をするため、削除する場合は、関数内で UITableViewCellEditingStyle.Deleteを使用します。
また、配列から該当の値を削除するため、removeAtIndex()関数も利用します。削除後は、再度NSUserDefaultsに値をセットし、最後にTableView全体を更新します。TableViewの更新には、先ほど作成したTableViewの変数にreloadData()と記述します。
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){ if editingStyle == UITableViewCellEditingStyle.Delete{ todoItem.removeAtIndex(indexPath.row) NSUserDefaults.standardUserDefaults().setObject(todoItem, forKey: "todoList") todolistTable.reloadData() } }
最後に、テーブル(リスト)を下に引っ張って更新機能を記述します。
これは決まり文句のようなもので、下記を記述します。
override func viewDidAppear(animated: Bool) { todolistTable.reloadData() }
ここまでできたらビルドして、アイテムの追加削除をしてみてください。以上で完成です。今回は初歩的なところまでの作成にしていますので、色々拡張してみてください。
では、以下にViewController.swiftとAddToDo.swiftの全コードを記述しておきます。
// // ViewController.swift // ToDoList // // Created by mosho on 2015/11/01. // Copyright © 2015年 mosho. All rights reserved. // import UIKit class ViewController: UIViewController,UITableViewDelegate { @IBOutlet weak var todolistTable: UITableView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if NSUserDefaults.standardUserDefaults().objectForKey("todoList") != nil { todoItem = NSUserDefaults.standardUserDefaults().objectForKey("todoList") as! [String] } } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return todoItem.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cellValue = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell") cellValue .textLabel?.text = todoItem[indexPath.row] return cellValue } func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){ if editingStyle == UITableViewCellEditingStyle.Delete{ todoItem.removeAtIndex(indexPath.row) NSUserDefaults.standardUserDefaults().setObject(todoItem, forKey: "todoList") todolistTable.reloadData() } } override func viewDidAppear(animated: Bool) { todolistTable.reloadData() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
// // AddToDo.swift // ToDoList // // Created by mosho on 2015/11/01. // Copyright © 2015年 mosho. All rights reserved. // import UIKit var todoItem = [String]() class AddToDo: UIViewController { @IBOutlet weak var itemText: UITextField! @IBAction func addItem(sender: AnyObject) { todoItem.append(itemText.text!) itemText.text = "" NSUserDefaults.standardUserDefaults().setObject(todoItem, forKey: "todoList") } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func touchesBegan(touches: Set, withEvent event: UIEvent?) { self.view.endEditing(true) } func textFieldShouldReturn(textField: UITextField!) -> Bool { itemText.resignFirstResponder() return true } }
また、今回作成したViewController.swiftとAddToDo.swiftは各リンクから取得可能です。ご参考までに。
では、次回はMapKitの使い方について説明したいと思います。