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

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

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

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

Swift

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

Q&A

解決済

1回答

1418閲覧

TableViewCellを保存する方法(UserDefaults)

Ytan

総合スコア39

Xcode

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

Swift

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

0グッド

1クリップ

投稿2020/04/05 14:32

実行したいこと

TableviewcellにtextFieldで出力した値を配列に入れTodoとして取り出しているのですが、アプリを閉じるとcellが消えてしまうのでUserDefaultsに保存したいのですがいまいちわかりません。

また,遷移先にtextViewを設け一言書けるようにもしたいのですが、こちらもcellの保存は第一にcellとは別で保存する必要があるともうのですがどうですか?

該当コード(ViewController)

Swift5

1import UIKit 2 3class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate { 4 5 6 @IBOutlet weak var textField: UITextField! 7 @IBOutlet weak var tableView: UITableView! 8 9 10 var textArray = [String]() 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 // Do any additional setup after loading the view. 15 16 tableView.delegate = self 17 tableView.dataSource = self 18 textField.delegate = self 19 20 } 21 22 override func viewWillAppear(_ animated: Bool) { 23 super.viewWillAppear(animated) 24 25 navigationController?.isNavigationBarHidden = true 26 27 if UserDefaults.standard.object(forKey: "todo") != nil{ 28 29 textArray = UserDefaults.standard.object(forKey: "todo") as! [String] 30 } 31 32 } 33 34 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 35 36 return textArray.count 37 38 } 39 40 func numberOfSections(in tableView: UITableView) -> Int { 41 42 return 1 43 } 44 45 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 46 47 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 48 49 cell.selectionStyle = .none 50 cell.textLabel?.text = textArray[indexPath.row] 51 cell.imageView?.image = UIImage(named: "profile") 52 cell.textLabel?.textColor = .white 53 54 return cell 55 56 } 57 58 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 59 60 let nextVC = storyboard?.instantiateViewController(identifier: "next") as! NextViewController 61 62 nextVC.todoString = textArray[indexPath.row] 63 64 navigationController?.pushViewController(nextVC, animated: true) 65 66 } 67 68 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 69 70 return view.frame.size.height/7 71 72 } 73 74 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 75 76 textArray.append(textField.text!) 77 textField.resignFirstResponder() 78 textField.text = "" 79 tableView.reloadData() 80 81 return true 82 83 } 84} 85

該当コード(NextViewController)

Swift5

1import UIKit 2 3class NextViewController: UIViewController { 4 5 var todoString = String() 6 7 8 @IBOutlet weak var textView: UITextView! 9 @IBOutlet weak var Todolabel: UILabel! 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 // Do any additional setup after loading the view. 15 16 Todolabel.text = todoString 17 18 } 19 20 override func viewWillAppear(_ animated: Bool) { 21 super.viewWillAppear(animated) 22 23 navigationController?.isNavigationBarHidden = false 24 } 25} 26

補足

if UserDefaults.standard.object(forKey: "todo"と一応呼び出しているのですがうまくは実証されませんでした。保存元がtextArrayではないのでしょうか?また保存したものを取り出すと思うのですがどのようにすれば良いですか?

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

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

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

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

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

TsukubaDepot

2020/04/05 15:22

> また,遷移先にtextViewを設け一言書けるようにもしたいのですが、こちらもcellの保存は第一にcellとは別で保存する必要があるともうのですがどうですか? ここの記述がよくわからないのですが、具体的にはどのようなことを行いたいのでしょうか。
Ytan

2020/04/05 23:27

cellひとつひとつにTextViewの文字を保存してcellを戻した時やアプリを閉じた時も保存されていて欲しいということですね。 個人的にTextViewはcellの配列ではなくTextView単体として保存するのか?と思ったので質問しました!
guest

回答1

0

ベストアンサー

[String]型のUserDefaultsを使った保存と呼び出しはこんな感じになります。

Swift

1import Foundation 2 3let todos = ["食う", "寝る", "遊ぶ"] 4 5// 保存 6UserDefaults.standard.set(todos, forKey: "todo") 7 8// 読み込み 9if let getData = UserDefaults.standard.stringArray(forKey: "todo") { 10 print(getData) 11} else { 12 print("error") 13} 14 15// object(forKey:)でも取得できるが、型変換が必要 16if let getData = UserDefaults.standard.object(forKey: "todo") as? [String] { 17 print(getData) 18} else { 19 print("error") 20} 21

適切な場所で保存し、適切な場所で読み出せばいいかと思います。

上記のサンプルはPlaygroundでも動くので、まずは簡単なサンプルを作り動かしてみることで動作を確認されてはいかがでしょうか。

--

ToDo のデータを保存したいということであれば、Cell に保存するというか、1件のToDoに対応するクラスを作り、それを配列にして扱った方が簡単です。

たとえば、

Swift

1class Todo { 2 var title: String 3 var todoDescription: String 4 5 init(title: String, description: String = "") { 6 self.title = title 7 self.todoDescription = description 8 } 9}

のような感じでクラスを作り、適切なところで

Swift

1var todoArray: [Todo] = []

といった感じでTodoクラスの配列を作り、

Swift

1 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 2 // 主要なところのみ掲載 3 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 4 cell.textLabel?.text = todoArray[indexPath.row].title 5 return cell 6 }

でテーブルセルに表示させたり、

Swift

1 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 2 let text = textField.text ?? "" 3 todoArray.append(Todo(title: text)) 4 5 tableView.reloadData() 6 // その他必要な処理 7 return true 8 9 }

で新規データを追加すればいいと思います。

同じような感じで、Todoの詳細(Todo.todoDescription)は遷移先でセットすればいいのではないでしょうか。

ちなみに、カスタムクラス(正確にはプロパティリスト)以外のクラスをUserDefaultsに保存するためには、さらにひと工夫必要です。

これについては過去の回答の後半に例がありますので、そちらも参考にしてみてください。

投稿2020/04/05 15:20

編集2020/04/06 00:41
TsukubaDepot

総合スコア5086

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

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

Ytan

2020/04/06 02:15

いつも丁寧な返答ありがとうございます。こちらで試してみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問