何気なく操作している左スワイプしてセルを削除するアクション。どのように実装されているか気になりませんか?
今回は、UITableViewのセルをスワイプして削除する方法を実装してみたいと思います。
私は、メモアプリを作成しているとき、セルを削除する方法がわからなくて、調べて実装しました。ある関数を追加することでセルをスワイプで削除できるようになります。
参考にしたサイトはこちらです。

注意が必要なのは、上記サイトは、画面表示上の削除だけの解説なっています。そのため、アプリを再起動すると削除したデータが復活します。私が作成していたメモアプリは、CoreDataというデータベースを使用しています。CoreDataにあるデータを削除しないと、再起動後、データが表示されてしまいます。なので、今回はCoreDataを使用してデータベース内のデータ管理をしてみたいと思います。
完成したら、このような動きになります。
プロジェクトを作成
最初は、プロジェクトを新規作成します。CoreDataはプロジェクトを作成するとき、項目にチェックを入れるとCoreDataに必要なファイルなどを追加することができます。
CoraDataを設定
CoraDataの設定をします。ENTITIESのところには、今回はEntityと名前を設定します。AttributesにTypeをStringのものを作成します。今回、名前はtestにします。
ストーリーボードを設定
ストーリーボードに、テーブルビューとボタンを配置していきます。テーブルビューのセルにIdentifierを設定します。今回は、例としてtestCellと入力します。
テーブルビューをViewController.swiftに接続します。接続するために、ViewController.swiftをエディタ上に表示します。下記の図の通りに操作してみてください。
「Assistant」をクリックするとViewController.swiftが表示されます。表示されたら、TableViewを選択してcontrolを押しながらドラッグします。そうすると、青い棒が表示されます。そうしたら、ViewController.swiftにドロップします。
ドロップをすると、下記のウィンドウが出てくるので、今回はNameのところに、testTableViewと入力します。
ボタンの設定をします。今回は、ボタンを押した時の動作について設定します。まずはボタンを選択してcontrolを押しながらドラッグします。そうしたら、ViewController.swiftにドロップします。
ドロップをすると、下記のウィンドウが出てくるので、今回はNameのところに、addTextと入力します。
コーディング
CoraDataのフレームワークを使用するために宣言します。
import CoreData
ViewController.swiftに変数を宣言します。
var textlist = [Entity]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
まずは、データを追加する関数を作成したいと思います。ボタンを押すとCoreDataにデータが追加され、セルにテキストが表示されます。
@IBAction func addText(_ sender: Any) {
//空のデータを追加
let newItem = Entity(context: self.context)
//テキストを追加
newItem.test = "test"
textlist.append(newItem)
//テーブルビューをリロード
testTableView.reloadData()
}
次にデータを読み込む関数を作成したいと思います。CoreDataのデータを読み込んで、データを宣言した配列に代入します。画面遷移先でCoreDataのデータを使用したい時は、必ずCoraDataの読み込みを忘れないようにしましょう。
func loadTextlist() {
let request : NSFetchRequest = Entity.fetchRequest()
do{
textlist = try context.fetch(request)
} catch {
print("Error loading checklist \(error)")
}
}
次にデータ内容を保存する関数を作成したいと思います。追加したり、削除したデータをCoreDataにデータ内容を保存します。
func saveTextlist() {
do {
try context.save()
} catch {
print("Error saving Item \(error)")
}
}
UITableViewDataSourceとUITableViewDelegateを継承させます。
extension ViewController: UITableViewDataSource, UITableViewDelegate {
}
上記のコード内にセルを表示させる関数を追加します。
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return textlist.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath)
cell.textLabel?.text = textlist[indexPath.row].test
return cell
}
}
次はUITableViewで、スワイプしてセルを削除する関数を実装します。この関数を追加すると、スワイプ削除のアクションを使用することができます。その関数の中に、CoreDataのデータを削除する処理を実装します。
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
let task = textlist[indexPath.row]
//データを削除
context.delete(task)
do {
textlist = try context.fetch(Entity.fetchRequest())
}
catch{
print("Error delete \(error)")
}
tableView.deleteRows(at: [indexPath], with: .automatic)
self.saveTextlist()
}
override func viewDidLoad()の中を下記のコードようにコーディングします。
override func viewDidLoad() {
super.viewDidLoad()
testTableView.delegate = self
testTableView.dataSource = self
self.loadTextlist()
self.saveTextlist()
}
全体のコードはこのような感じです。
import UIKit
import CoreData
class ViewController: UIViewController {
@IBOutlet weak var testTableView: UITableView!
var textlist = [Entity]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
override func viewDidLoad() {
super.viewDidLoad()
testTableView.delegate = self
testTableView.dataSource = self
self.loadTextlist()
self.saveTextlist()
}
//MARK: - CoreData 読み込み
func loadTextlist() {
let request : NSFetchRequest = Entity.fetchRequest()
do{
textlist = try context.fetch(request)
} catch {
print("Error loading checklist \(error)")
}
}
//MARK: - CoreData 保存する
func saveTextlist() {
do {
try context.save()
} catch {
print("Error saving Item \(error)")
}
}
//MARK: - セルにデータを追加
@IBAction func addText(_ sender: Any) {
//空のデータを追加
let newItem = Entity(context: self.context)
//テキストを追加
newItem.test = "test"
textlist.append(newItem)
//テーブルビューをリロード
testTableView.reloadData()
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return textlist.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath)
cell.textLabel?.text = textlist[indexPath.row].test
return cell
}
//MARK: - スワイプ削除の処理
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
// 先にデータを削除しないと、エラーが発生する。
let task = textlist[indexPath.row]
//データを削除
context.delete(task)
do {
textlist = try context.fetch(Entity.fetchRequest())
}
catch{
print("Error delete \(error)")
}
tableView.deleteRows(at: [indexPath], with: .automatic)
self.saveTextlist()
}
}
以上でスワイプ削除して、CoraData内のデータも削除されるアプリが完成します。