質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

550閲覧

【swift】テーブルビューのセルスワイプ削除

yamadayeah90

総合スコア6

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/06/04 14:40

現在、選択した日付を抽出条件として、realmデータベースからデータを持ってきてテーブルビューのセルに表示しているのですが、そのセルに対してスワイプして削除するという処理を追加したいのですが、インターネットでの処理を当て込んでもうまくいきません。

エラーの状態からテーブルをリロードすると解決するという情報もあり、reload処理も追加しているのですが、下記のエラーが出てしまいます。

下記のエラーの対処方法はありますでしょうか?

エラー

Thread 1: "Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). Table view: <UITableView: 0x7f953b009800; frame = (0 521; 390 167); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x6000038c6790>; layer = <CALayer: 0x600003799240>; contentOffset: {0, 0}; contentSize: {390, 61.333333333333336}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <myaccount.calendar: 0x7f953a81e110>>"

テーブル作成処理

swift

1 //データベース上に保存されているデータを配列に格納する。 2 func getModel(date:String) -> [[String:String]] { 3 let realm = try! Realm() 4 let results = realm.objects(calender.self).filter("date == %@",date) 5 var param: [[String:String]] = [] 6 for result in results { 7 param.append(["reason": result.outreason, 8 "payout": String(result.payout), 9 "date": result.date 10 ]) 11 12 } 13 return param 14 } 15 16 //セルの編集許可 17 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 18 { 19 return true 20 } 21 22 func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 23 let action = UIContextualAction(style: .destructive, 24 title: "削除") { (action, view, completionHandler) in 25 self.showAlert(deleteIndexPath: indexPath) 26 completionHandler(true) 27 } 28 action.backgroundColor = .red 29 let configuration = UISwipeActionsConfiguration(actions: [action]) 30 return configuration 31 } 32 33 func showAlert(deleteIndexPath indexPath: IndexPath) { 34 let dialog = UIAlertController(title: "削除", 35 message: "削除してよろしいですか?", 36 preferredStyle: .alert) 37 var array = getModel(date: labelDate.text!) 38 dialog.addAction(UIAlertAction(title: "削除", style: .default, handler: { (_) in 39 array.remove(at: indexPath.row) 40 self.TableView.deleteRows(at: [indexPath], with: .automatic) 41 self.TableView.reloadData() 42 })) 43 dialog.addAction(UIAlertAction(title: "嫌や", style: .cancel, handler: nil)) 44 self.present(dialog, animated: true, completion: nil) 45 } 46} 47 48extension calendar: UITableViewDelegate, UITableViewDataSource { 49 //セルの個数を返すメソッド 50 func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int { 51 let length:Int = getModel(date: labelDate.text!).count 52 return length 53 } 54 55 //セクション内に表示するセルのテキストを返すメソッド 56 func tableView(_ tableView: UITableView, cellForRowAt IndexPath: IndexPath) -> UITableViewCell { 57 let cell = TableView.dequeueReusableCell(withIdentifier: "calendarCell", for: IndexPath) 58 let data = getModel(date: labelDate.text!)[IndexPath.row] 59 let outReasonLabel = cell.contentView.viewWithTag(1) as! UILabel 60 let dateLabel = cell.contentView.viewWithTag(2) as! UILabel 61 let payoutLabel = cell.contentView.viewWithTag(3) as! UILabel 62 if let reason = data["reason"]?.description, 63 let date = data["date"]?.description, 64 let payout = data["payout"]?.description { 65 outReasonLabel.text = reason 66 dateLabel.text = date 67 payoutLabel.text = "\(payout)円" 68 } 69 70 return cell 71 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

swift

1var array = getModel(date: labelDate.text!) 2dialog.addAction(UIAlertAction(title: "削除", style: .default, handler: { (_) in 3 array.remove(at: indexPath.row) 4 self.TableView.deleteRows(at: [indexPath], with: .automatic) 5 self.TableView.reloadData() 6}))

これは、データペースに格納されているデータをarrayというローカル変数の配列に格納し、そのローカル変数(array)の配列要素を削除しているだけですから、テーブル表示の元になっているデータは何も削除されておらず、「削除したはずなのに行数が違う。」というエラーになったのだと思います。

Realmのデータペースから対象データを削除した上で deleteRows メソッドを発行する必要があります。

なお、ここで reloadData を実施すると、 deleteRows によるセルの削除アニメーションがキャンセルされてしまいますので、、 reloadData は実施しない方が良いと思います。削除アニメーションが不要なら、 deleteRows は実施しないで reloadData だけ実施すれば良いです。いずれにしても、テーブル表示の元になっているデータを削除してから deleteRows または reloadData を実施すれば良いです。

投稿2022/06/07 23:15

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問