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

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

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

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

2512閲覧

Realmのデータの追加について

退会済みユーザー

退会済みユーザー

総合スコア0

Realm

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

1グッド

0クリップ

投稿2018/06/20 06:46

swift

1import UIKit 2import RealmSwift 3 4extension UIColor { 5 class func rgb(r: Int, g: Int, b: Int, alpha: CGFloat) -> UIColor{ 6 return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: alpha) 7 } 8} 9 10class TopViewViewController: UIViewController,UITableViewDataSource,UITableViewDelegate { 11 12 13 @IBOutlet weak var TopViewTabelView: UITableView! 14 let ToDo = TopTodo() 15 var todoItem: Results<TopTodo>! 16 17 18 override func viewDidLoad() { 19 super.viewDidLoad() 20 21 // 永続化されているデータを取りだす 22 do{ 23 let realm = try Realm() 24 self.todoItem = realm.objects(TopTodo.self) 25 self.TopViewTabelView.reloadData() 26 }catch{ 27 28 } 29 30 navigationController?.navigationBar.prefersLargeTitles = true //これがやりたかった設定やメモ帳のナビゲーションの可変のやつ 31 navigationItem.title = "データベース" 32 TopViewTabelView.tableFooterView = UIView(frame: .zero) 33 self.view.backgroundColor = UIColor.rgb(r: 250, g: 204, b: 125, alpha: 1) 34 TopViewTabelView.frame = CGRect(x: 0, y: 64, width: 375, height: 667) 35 36 } 37 38 39 40 41 @IBAction func addBtr(_ sender: Any) { 42 let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert) 43 44 // OKボタンの設定 45 let okAction = UIAlertAction(title: "OK", style: .default, handler: { 46 (action:UIAlertAction!) -> Void in 47 48 // OKを押した時入力されていたテキストを表示 49 if let textFields = alert.textFields { 50 51 // アラートに含まれるすべてのテキストフィールドを調べる 52 for textField in textFields { 53 //self.item.insert(textField.text!, at: 0) 54 55 let newTodo = self.ToDo 56 do{ 57 let realm = try Realm() 58 try realm.write({ () -> Void in 59 realm.add(newTodo) 60 print("ToDo Saved") 61 self.ToDo.item.append(textField.text!) 62 self.TopViewTabelView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) 63 print(textField.text!) 64 }) 65 }catch{ 66 print("Save is Faild") 67 } 68 } 69 self.TopViewTabelView.reloadData() 70 } 71 }) 72 alert.addAction(okAction) 73 74 // キャンセルボタンの設定 75 let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 76 alert.addAction(cancelAction) 77 78 // テキストフィールドを追加 79 alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in 80 textField.placeholder = "テキスト" 81 }) 82 alert.view.setNeedsLayout() // シミュレータの種類によっては、これがないと警告が発生 83 84 self.present(alert, animated: true, completion: nil) 85 } 86 87 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 88 return todoItem.count 89 } 90 91 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 92 let Cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 93 /*let now = NSDate() // 現在日時の取得 94 95 let dateFormatter = DateFormatter() 96 dateFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale? // ロケールの設定 97 dateFormatter.dateFormat = "yyyy年MM月dd日 HH:mm"//:ss" // 日付フォーマットの設定 98 99 let dateString = dateFormatter.string(from: now as Date) 100 print(dateString) // -> 2014/06/25 02:13:18*/ 101 102 let object = todoItem[indexPath.row] 103 Cell.textLabel?.text = object.item 104 Cell.textLabel?.textAlignment = NSTextAlignment.center 105 /*Cell.detailTextLabel?.text = dateString 106 Cell.detailTextLabel?.textAlignment = NSTextAlignment.right*/ 107 return Cell 108 } 109 110 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 111 112 113 if(editingStyle == UITableViewCellEditingStyle.delete) { 114 do{ 115 let realm = try Realm() 116 try realm.write { 117 realm.delete(self.todoItem[indexPath.row]) 118 } 119 TopViewTabelView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade) 120 }catch{ 121 } 122 TopViewTabelView.reloadData() 123 } 124 } 125 126 127 128 override func didReceiveMemoryWarning() { 129 super.didReceiveMemoryWarning() 130 // Dispose of any resources that can be recreated. 131 } 132 133}

swift

1import RealmSwift 2 3class TopTodo: Object{ 4 @objc dynamic var item = "" 5}

実現したいこと

tableViewに追加したデータを永続的に保存したい。

困っていること

現状ではtableViewにalertでデータを追加しているのですが一つしかデータを追加できなくて困っています。2つ目を追加しようとボタンをタップすると落ちていまう。(理由が分からない)
また、todoの一覧部分の永続保存の処理までは一応出来たが遷移先のtableViewのデータの保存の仕方が分からなくて困っている。(labelなど複雑な処理がある為)

gitに上げているので見て頂けると分かりやすいと思います
https://github.com/haruka22/new-project

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

ご提示いただいたGithubのソースを試してみたところ
原因としてはinsertRowsをしたあとのtableViewの更新でDatasourceが持っているデータ数と表示するセルの数に不整合が生じているからだと思います。

swift

1// アラートに含まれるすべてのテキストフィールドを調べる 2for textField in textFields { 3 4 let newTodo = self.ToDo 5 do{ 6 let realm = try Realm() 7 try realm.write({ () -> Void in 8 realm.add(newTodo) 9 print("ToDo Saved") 10 self.ToDo.item.append(textField.text!) 11 self.TopViewTabelView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) 12 print(textField.text!) 13 }) 14 }catch{ 15 print("Save is Faild") 16 } 17} 18self.TopViewTabelView.reloadData()

try realm.write中でself.TopViewTabelView.insertRowsを呼んでいますが、
この時点だとRealmにはまだデータが追加されていない(=まだコミットされていないため)
一度トランザクションを抜けてコミットをする必要があります。

また、todoItemの更新が行われていないため、rowを追加してもTableViewの更新時点で
todoItemの数(numberOfRowsInSectionで使われている数)はTableViewでinsertしている分の数足りなくなっています。

下記のようにしたらどうなりますでしょうか?

swift

1// アラートに含まれるすべてのテキストフィールドを調べる 2for textField in textFields { 3 4 // 変数で持つ必要はないのではないでしょうか? 5 let newTodo = TopTodo() 6 newTodo.item = textField.text! 7 do{ 8 let realm = try Realm() 9 10 // トランザクション開始 11 try realm.write({ () -> Void in 12 realm.add(newTodo) 13 print("ToDo Saved") 14 }) 15 // ここでトランザクションが終了 16 17     // ここでtodoItemの更新 18 self.todoItem = realm.objects(TopTodo.self) 19 self.TopViewTabelView.insertRows(at: [IndexPath(row: 0, section: 0)],with: UITableViewRowAnimation.automatic) 20 print(textField.text!) 21 22 }catch{ 23 print("Save is Faild") 24 } 25} 26self.TopViewTabelView.reloadData() 27

あまり回答できる時間がなくて恐縮ですが、ご検討いただけましたら幸いです。
何卒よろしくお願い致します。

投稿2018/06/20 22:38

newmt

総合スコア1277

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

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

退会済みユーザー

退会済みユーザー

2018/06/21 04:50

ありがとうございます。見事に解決しました。処理を書く順番が問題だったんですね。 それと差し支えが無けれあば教えて頂きたいんですが、Objectのクラスに追加で@objc dynamic var date = NSDate()を追加したところnumberOfRowsInSectionでエラーが出てしまいました。 以下がエラーコードになります。 Fatal error: Unexpectedly found nil while unwrapping an Optional value 色々調べて見たのですがどこにもこのようなエラーで困っている人がいなく参考に出来る記事がなくて困っています。もしお時間ありましたらご教授して頂けると幸いです。
退会済みユーザー

退会済みユーザー

2018/06/24 18:05

どうしても分からない箇所がありご教授願いたいです。 Objectクラスにて、追加するセルの名前の他にサブタイトルで日時を追加したく、クラスの中に@objc dynamic var date = NSDate()を追加したところnumberOfRowsInSectionでアンラップエラーが起きてしまいその対処に苦慮しています。 エラーコードとしては、オプショル型が問題なのかなと思うのですがどこがいけないのかが分からないです。 差し支えなければご教授して頂けないでしょうか? よろしくお願いします。 https://teratail.com/questions/132346
退会済みユーザー

退会済みユーザー

2018/07/10 17:41

お忙し中すいません。先日は懇切に教えて頂きありがとうございました。 また、分からないところがあり色々ネットなどでも調べて見たのですが解決方法が見つからず苦慮しています。もし宜しければお時間ある時にご教授願いたいです。 具体的に説明しますと、現在カスタムアラートを製作しており、その過程でアラート内に数字キーボードを用意しています。 そして、用意したキーボードからtextFieldsに値を入力していくのですがその際の条件分岐の仕方が分からなくて困っています。 やりたい事としては、セグメントコントロールで選択したテキストフィールドのみ入力を行えるようにしたいのですがそのやり方についてどうしても分からなくて困っています。 そのため、お時間のある時に御教授して頂けたら幸いです。何卒宜しくお願いいたします。 https://teratail.com/questions/135363
退会済みユーザー

退会済みユーザー

2018/08/04 14:24

お久しぶりです。お忙し中すいません。現在ios-chartsにて入力したデータを折れ線グラフにするグラフを製作しています。 大まかな部分は出来たのですが、入力した時の日付を横軸に表示させたいのですがどうも上手くいかなくて困っています。 そのため、もしお時間がありましたら見ていただけないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問