🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Realm

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

Swift

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

Q&A

解決済

1回答

1099閲覧

Realmに空データしか登録出来ない

takuwo1031

総合スコア4

Realm

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

Swift

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

0グッド

0クリップ

投稿2021/01/24 07:29

編集2021/01/24 08:22

前提・実現したいこと

CollectionViewとInputViewという2つの画面をもつアプリで、
InputViewで名前や写真を入力して完了ボタンを押すと、collectionViewで登録された情報が一覧で見れるようにしたいです。

発生している問題・エラーメッセージ

完了ボタンを押してCollectionViewに戻ると、データ数は増えているが、全て空の状態になっている

該当のソースコード

Teammate

1import Foundation 2import RealmSwift 3 4class Teammate: Object { 5 // ID 6 dynamic var id = 0 7 // 名前 8 dynamic var name = "" 9 // 写真 10 dynamic var photo = Data() 11}

InputViewController

1import UIKit 2import RealmSwift 3 4class InputViewController: UIViewController, UIImagePickerControllerDelegate & UINavigationControllerDelegate { 5 6 @IBOutlet weak var imageView: UIImageView! 7 @IBOutlet weak var infoView: UIView! 8 @IBOutlet weak var nameText: UILabel! 9 10 var name = "" 11 var imagePhoto: UIImage! 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 // Do any additional setup after loading the view. 16 17 } 18 19 @IBAction func tapAction(_ sender: Any) { 20 if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { 21 // 写真を選ぶビュー 22 let pickerView = UIImagePickerController() 23 // 写真の選択元をカメラロールにする 24 pickerView.sourceType = .photoLibrary 25 // デリゲート 26 pickerView.delegate = self 27 //編集を可能にする 28 pickerView.allowsEditing = true 29 // ビューに表示 30 self.present(pickerView, animated: true) 31 } 32 } 33 34 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 35 if info[UIImagePickerController.InfoKey.originalImage] != nil { 36 // 選択した写真を取得する 37 let image = info[UIImagePickerController.InfoKey.editedImage] as! UIImage 38 // ビューに表示する 39 imageView.image = image 40 imagePhoto = image 41 // 写真を選ぶビューを引っ込める 42 self.dismiss(animated: true) 43 } 44 } 45 46 //登録ボタン 47 @IBAction func okayBtnAction(_ sender: Any) { 48 //データの更新 49 let realm = try! Realm() 50 let newData = Teammate() 51 try! realm.write { 52 newData.name = nameText.text! 53 newData.photo = imagePhoto.jpegData(compressionQuality: 0.5)! as Data 54 realm.add(newData) 55 print(newData.name) 56 print(newData.photo) 57 } 58 self.dismiss(animated: true, completion: nil) 59 } 60 61 @objc func changeName(nm: String){ 62 nameText.text = nm 63 }

InfoViewController

1import UIKit 2 3class InfoViewController: UIViewController { 4 5 @IBOutlet weak var nameTextField: UITextField! 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 nameTextField.addTarget(self, action: #selector(changeText), for: .editingChanged) 10 11 // Do any additional setup after loading the view. 12 } 13 14 @objc func changeText(){ 15 let parent = self.parent as! InputViewController 16 parent.changeName(nm: nameTextField.text!) 17 parent.name = nameTextField.text! 18 }

ViewController

1import UIKit 2import Charts 3import RealmSwift 4 5class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 6 7 @IBOutlet weak var collectionView: UICollectionView! 8 9 //Realmインスタンスを取得 10 let realm = try! Realm() 11 12 //Teammateが格納されているリスト 13 var teammate = try! Realm().objects(Teammate.self) 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 // Do any additional setup after loading the view. 18 collectionView.dataSource = self 19 20 for human in teammate { 21 print("name: (human.name)") 22 } 23 24 // レイアウトを調整 25 let layout = UICollectionViewFlowLayout() 26 27 layout.sectionInset = UIEdgeInsets(top: 15, left: 15, bottom: 15, right: 15) 28 collectionView.collectionViewLayout = layout 29 } 30 31 //セル表示数 32 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 33 // 表示するセルの数 34 return teammate.count 35 } 36 37 //各セルの内容を返すメソッド 38 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 39 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell 40 let person = teammate[indexPath.row] 41 //写真のデータ型の変換 42 var imageData: UIImage? = UIImage(data: person.photo as Data) 43 if imageData == nil { 44 imageData = UIImage(named: "sample") 45 } 46 //Cellにセット 47 cell.setup(name: person.name, icon: imageData!) 48 // セルの色 49 //cell.backgroundColor = .lightGray 50 return cell 51 } 52 53 //デザイン 54 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 55 let horizontalSpace : CGFloat = 20 56 let cellSize : CGFloat = self.view.bounds.width / 3 - horizontalSpace 57 return CGSize(width: cellSize, height: cellSize) 58 } 59 60 //入力画面から返ってきたときにCollectionViewを更新 61 override func viewWillAppear(_ animated: Bool) { 62 super.viewWillAppear(animated) 63 collectionView.reloadData() 64 } 65}

CollectionViewCell

1import UIKit 2 3class CollectionViewCell: UICollectionViewCell { 4 @IBOutlet weak var cellName: UILabel! 5 @IBOutlet weak var cellImage: UIImageView! 6 7 func setup(name: String, icon: UIImage){ 8 cellName.text = name 9 cellImage.image = icon 10 } 11}

試したこと

Realm Studioを使ってデータを確認しましたが、全て空でした

補足情報(FW/ツールのバージョンなど)

iOS 14.3
Xcode 12.3
RealmSwift 10.5.0

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

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

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

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

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

guest

回答1

0

ベストアンサー

完了ボタンを押してCollectionViewに戻ると、データ数は増えているが、全て空の状態になっている

これは、
1)Realm のデータとしては追加されている
2)ViewController に戻ってきた時に表示されない

ということでしょうか。

一応、コード的には画像や名前は登録されているので(実装して確認しました)、アプリを再起動させれば登録した画像などは表示されるはずです。

細かい実装が分からないのでなんとも言えない部分がありますが、ViewController の

Swift

1 //入力画面から返ってきたときにCollectionViewを更新 2 override func viewWillAppear(_ animated: Bool) { 3 super.viewWillAppear(animated) 4 collectionView.reloadData() 5 }

の部分ですが、iOS13 以降は遷移先からの画面から戻ってきてもこの部分は実行されません。

実行されません、というのは語弊があるのですが、Segue を使った遷移が通常の「show」の場合は実行されないように変更されています。

コードに手を入れることなく、元の画面に戻ってきた時に viewWillAppear(_:)を呼び出すためには、上記リンク先のように表示方法を変更する必要があります。

上記リンク以外でも、たとえばPresent Modally -> Full Screen でも可能です。

コードに手を入れるとなると、Delegate パターンや Observer パターンを使い、呼出先から呼出元に対し、CollectionView をリロードするように設計する必要があるかと思います。

投稿2021/01/24 14:50

TsukubaDepot

総合スコア5086

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

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

takuwo1031

2021/01/24 23:46 編集

ご回答ありがとうございます。 状態としては、Realmのデータ自体がそもそも空の状態で登録されています。 (Realm Studioを使って確認したところ、何も入っていない行が増えている状態でした) また、viewWillAppearの件もありがとうございます。 こちらはFull Screenに設定していたので、おそらく大丈夫かと思いました。 実装いただいて動いたと教えていただいたので、新しくプロジェクト作成して一から再作成してみようと思います。
TsukubaDepot

2021/01/25 00:04

基本的にご提示いただいたコードをそのまま使っているのですが、意図が読めない部分(コードが足りない部分)は少し解釈を変えて実装している部分もあります。 やはり動かない、ということであれば、こちらで試した内容を GitHub などに上げますので、改めてコメントしていただければと思います。
takuwo1031

2021/01/25 09:07

ご回答ありがとうございます。 こちら試した内容ご共有いただくことは可能でしょうか。 改めてやってみたのですが、上手くいかず、よろしくお願い致します。
TsukubaDepot

2021/01/25 09:29

https://github.com/tsukubadepot/318142RealmCollectioView 上記リポジトリから clone ないしダウンロードしていただけますでしょうか。 一部推測でコードを変えている部分もありますが、概ね意図した流れになっているのではないかと思います。 左下の item ボタンで登録画面、次の画面の Photo で写真選択、その後 Add で登録し、ViewController に戻ると登録した写真とランダムな文字列で登録されていると思います。 CollectionView などの Constraint などはかなり適当なので、そのあたりはご容赦ください。
takuwo1031

2021/01/25 09:44

ご丁寧にありがとうございます! 参考にさせていただきます。
takuwo1031

2021/01/25 13:56

出来ました! 原因はわからなかったですが、出来て良かったです。 ご丁寧にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問