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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

2351閲覧

[Swift]UserDefaultsで保存したデータをCollectionViewCellに表示させ続ける方法

s1209

総合スコア13

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/05/19 13:26

編集2018/05/20 14:51

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

UserDefaultsで保存したデータを、シミュレーター再起動後も表示させたいです。
xcodeのシミュレーターを再起動すると表示が消えてしまいます。
userDefaultsには保存されたままなので、表示させるためのコードが間違っていると思うのですが、どこを書き直したらいいかわかりません。

該当のソースコード(一部省略)

Swift

1 2import UIKit 3 4class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 5 6 static var cellNumber: Int = 0 7 @IBOutlet weak var collectionView: UICollectionView! 8 9 static var testArray: [Class] = [] 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 collectionView.delegate = self 15 collectionView.dataSource = self 16 17 collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell") 18 } 19 20 21 override func viewWillAppear(_ animated: Bool) { 22 23// 取得 24 if let data = UserDefaults.standard.object(forKey: "TimeTable") as? Data, let array = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Class] { 25 print("array:(array)") 26 } else { 27 print("Error") 28 } 29 print("testArray:(ViewController.testArray)") 30 collectionView.reloadData() 31 } 32 33 34 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 35 36 ViewController.cellNumber = indexPath.row 37 38 if ViewController.cellNumber == indexPath.row { 39 print("セル番号:(indexPath.row)") 40 } 41 42 performSegue(withIdentifier: "Modal1", sender: self) 43 } 44 45 46// セルの内容 47 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 48 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell 49 cell.backgroundColor = UIColor.groupTableViewBackground 50 51 if let data = ViewController.testArray.first(where: { $0.cellNumber == indexPath.row }) { 52 cell.classLabel.text = data.className 53 cell.roomLabel.text = data.roomName 54 } else { 55 cell.classLabel.text = "" 56 cell.roomLabel.text = "" 57 } 58 return cell 59 } 60 61 func numberOfSections(in collectionView: UICollectionView) -> Int { 62 return 1 63 } 64 65 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 66 67 return 36 68 } 69 70 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 71 let cellSize = CGSize(width: collectionView.frame.width / 6 - 1, height: collectionView.frame.height / 6 - 1) 72 73 return cellSize 74 } 75 76 77 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 78 return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) 79 } 80 81 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 82 return 1 83 } 84 85 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 86 return 1 87 } 88 89} 90

Swift

1 2import UIKit 3 4class Class: NSObject, NSCoding { 5 6 7 let className: String 8 let roomName: String 9 let cellNumber: Int 10 11 init(className: String, roomName: String, cellNumber: Int) { 12 13 self.className = className 14 self.roomName = roomName 15 self.cellNumber = cellNumber 16 } 17 18 func encode(with aCoder: NSCoder) { 19 aCoder.encode(self.className, forKey: "name") 20 aCoder.encode(self.roomName, forKey: "room") 21 aCoder.encode(self.cellNumber, forKey: "number") 22 } 23 24 required init?(coder aDecoder: NSCoder) { 25 self.className = aDecoder.decodeObject(forKey: "name") as! String 26 self.roomName = aDecoder.decodeObject(forKey: "room") as! String 27 self.cellNumber = aDecoder.decodeInteger(forKey: "number") 28 } 29} 30 31class Edit: UIViewController, UITextFieldDelegate { 32 33 @IBOutlet weak var classTextField: UITextField! 34 @IBOutlet weak var roomTextField: UITextField! 35 36 override func viewDidLoad() { 37 super.viewDidLoad() 38 39 } 40 41 42 @IBAction func tappedButton(_ sender: UIButton) { 43 44 let classData = Class(className:classTextField.text!, roomName: roomTextField.text!, cellNumber: ViewController.cellNumber) 45 ViewController.testArray.append(classData) 46 47// 保存 48 UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: ViewController.testArray), forKey: "TimeTable") 49 UserDefaults.standard.synchronize() 50 51// print("配列の中身:(ViewController.testArray)") 52 53 dismiss(animated: true) {} 54 } 55}

試したこと

ViewControllerのviewWillAppear内でprint(array)をしてみたところ、再起動後も正しくprint(array)が出力されたため、cellForItemAtのコードが間違っていると推測しました。

回答の追記・修正依頼について
viewWillAppear内でprint(ViewController.testArray)をしてみたところ、シミュレーター再起動後にtestArrayが空になっていることがわかりました。

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

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

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

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

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

newmt

2018/05/19 21:49

indexPath.rowに一致するcellNumberのデータは存在していますでしょうか?
s1209

2018/05/20 02:10

追記・修正依頼ありがとうございます。cellNumberのデータとはどういうものでしょうか?ViewControllerのtestArrayにTextFieldとcellNumberを保存するように書いたつもりなのですが、それとは違うのでしょうか?。
退会済みユーザー

退会済みユーザー

2018/05/20 02:52 編集

testArrayの内容を表示していると思うのですが、データを取得した後に、print(testArray)した結果はどうなるでしょうか? override func viewWillAppearの中の collectionView.reloadData()の上でprint(testArray)してみてください。
s1209

2018/05/20 04:55

ありがとうございます。上記の場所でprint(ViewController.testArray)をしてみたところ、再起動すると空になっていました。。。
退会済みユーザー

退会済みユーザー

2018/05/20 05:08 編集

print(array)のarrayの内容は、userDefaultに保存した、collectionViewに表示したい情報でしょうか? でしたら、それをif let 内でtestArrayに入れてあげればどうなりますか?
s1209

2018/05/20 13:55 編集

そうです!一応print内容をペーストしておきました。cellForItemAt内でarrayにtestArrayを代入するということでしょうか?
退会済みユーザー

退会済みユーザー

2018/05/20 14:40

viewWillAppearの //取得のところで、 print("array:\(array)")でarrayにデータが入っているなら、そこで testArray = arrayしてあげたらどうでしょう?
s1209

2018/05/20 14:46

理解力不足で申し訳ありません。ありがとうございました!上記の方法で解決いたしました。
退会済みユーザー

退会済みユーザー

2018/05/20 14:51 編集

よかったですね。解決方法を記入して解決済みでしたらよきにはからってください。
guest

回答1

0

自己解決

Swift

1 override func viewWillAppear(_ animated: Bool) { 2 3// 取得 4 if let data = UserDefaults.standard.object(forKey: "TimeTable") as? Data, let array = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Class] { 5 ViewController.testArray = array 6 print("array:(array)") 7 } else { 8 print("Error") 9 } 10 print("testArray:(ViewController.testArray)") 11 collectionView.reloadData() 12 }

回答の追記・修正依頼を元に、viewWillAppearのif let内でtestArray=arrayとしたら、シミュレーター再起動後もデータを表示させることができました。

投稿2018/05/20 14:53

s1209

総合スコア13

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問