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

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

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

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

Q&A

解決済

3回答

480閲覧

ToDOアプリでToDoListが表示されない

kinu221

総合スコア26

Swift

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

0グッド

1クリップ

投稿2018/09/15 14:50

編集2018/09/26 06:36

ToDOアプリでToDoListが表示されない

swift4でToDoアプリを作成しているのですが、Add画面でToDoリストに内容を追加したのですが、ToDoListに追加した内容が表示されませんので、アドバイスを頂きたいです。

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

ToDoListに追加した内容が表示されない

該当のソースコード

swift

1-ViewController.swift- 2import UIKit 3 4class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 5 6 @IBOutlet weak var tableView: UITableView! 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 // Do any additional setup after loading the view, typically from a nib. 11 if UserDefaults.standard.object(forKey: "TodoList") != nil { 12 todoItem = UserDefaults.standard.object(forKey: "TodoList") as! [String] 13 } 14 } 15 16 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 17 return todoItem.count 18 } 19 20 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 21 //変数を作る 22 let TodoCell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "TodoCell", for: indexPath) 23 //変数の中身を作る 24 TodoCell.textLabel!.text = todoItem[indexPath.row] 25 //戻り値の設定(表示する中身) 26 return TodoCell 27 } 28 29 30 31 32 override func didReceiveMemoryWarning() { 33 super.didReceiveMemoryWarning() 34 // Dispose of any resources that can be recreated. 35 } 36 37 38} 39

swift

1-AddController.swift- 2import UIKit 3 4var todoItem = [String]() 5 6class AddController: UIViewController { 7 8 @IBOutlet weak var TodoTextField: UITextField! 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 13 // Do any additional setup after loading the view. 14 } 15 16 @IBAction func TodoAddButton(_ sender: Any) { 17 todoItem.append(TodoTextField.text!) 18 TodoTextField.text = "" 19 //変数の中身をUDに追加 20 UserDefaults.standard.set(todoItem, forKey: "TodoList" ) 21 } 22 23 24 25 override func didReceiveMemoryWarning() { 26 super.didReceiveMemoryWarning() 27 // Dispose of any resources that can be recreated. 28 } 29 30 31 /* 32 // MARK: - Navigation 33 34 // In a storyboard-based application, you will often want to do a little preparation before navigation 35 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 36 // Get the new view controller using segue.destinationViewController. 37 // Pass the selected object to the new view controller. 38 } 39 */ 40 41}

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

Xcode ver.9.4.1
swift4
Main.storyboardの画面
イメージ説明
イメージ説明
イメージ説明
【コンソール画面に表示される内容】
![イメージ説明]
【TodoAddButton】
イメージ説明
【20180926時点でのソースコード】
イメージ説明

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

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

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

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

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

xAxis

2018/09/16 04:36

AddControllerのtextFieldでなにかを入力した後にViewControllerに戻ってますがその時Cellは増えていますか?
kinu221

2018/09/16 04:53

cellは増えていません。UserDefaultsでデータを保存しているのですが反映されていない状態です。
guest

回答3

0

ベストアンサー

まず今書かれているコードにはいくつか問題があります。の前に事前確認を。

確認事項

コード内にtableView.datasource = self等デリゲートの設定が書かれていませんがStoryboard上で設定されているものとします。また、UITableViewCellのStyleはBasicになっているものとします。

では問題点に入ります。

グローバル変数

グローバル変数は少ないコードでは問題にならないことの方が多いですがコード量が増えるとバグの温床になります。なので習慣としてグローバル変数は極力作らない、可能なら全く作らない、とした方がデバッグが楽チンです。
ということでAddController.swift内に書かれているグローバル変数todoItemはViewController.swift内のViewControllerのメンバにしてしまいましょう。
じゃあどうやってAddControllerのtextFieldの内容を反映するか、ですがそれは次の問題点とも関わるので次で触れます。

swift

1class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 2 var todoItem = [String]() 3 4 //以下略 5}

addControllerからViewControllerへ画面遷移する際にunwindsegueが設定されていない

任意のViewController_A(以下ViewControllerをVCと略す)からVC_Bへ画面遷移する際にはsegueを接続します。が、VC_BからVC_Aに画面遷移する際、つまり戻る際にはunwindsegueと言うものを使用します。通常StoryboardでVC_BからVC_Aにsegueで接続する方法とは少々異なるやり方です。

現状のコードを再利用するなら、AddController内の

swift

1 @IBAction func TodoAddButton(_ sender: Any) { 2 todoItem.append(TodoTextField.text!) 3 TodoTextField.text = "" 4 //変数の中身をUDに追加 5 UserDefaults.standard.set(todoItem, forKey: "TodoList" ) 6 }

このコードを削除して、ViewController内に以下のように追加します。

swift

1 @IBAction func TodoAddButton(segue: UIStoryboardSegue) { 2     //segue.sourceとsegue.destinationはセットでよく使います 3 //sourceは遷移元、destinationは遷移先です 4 guard let VC = segue.source as? AddController else { 5 fatalError("ViewController does not exist") 6 } 7 guard let text = VC.TodoTextField.text else { 8 fatalError() 9 } 10 todoItem.append(text) 11 UserDefaults.standard.set(todoItem, forKey: "TodoList" ) 12 }

こうすることで画面遷移元と画面遷移先の情報のやり取りが可能になります。

その後、Main.storyboardを開き、AddControllerからViewControllerへ伸びているsegueと「戻る」と書かれたBarButtonItem(かな?)を削除します(ついでにNavigationBarも削除しちゃってもいいと思います)。次に画面左部のViewController SceneをクリックするとViewControllerの画面の上に三つボタンが現れます。今回使うのは三つのボタンの一番右側のサーモンピンクっぽい色のボタン(exit)です。「add」と書かれているUIButtonを普段segueを接続するようにexitと接続します。するとToDoAddButtonWithSegueという項目が現れるのでその項目をクリックします。
これでSimulatorで「add」と書かれているUIButtonをタップするとViewControllerへ戻れるようになります。

本題

質問では内容が表示されない、とのことですが実は今回色々書いた中でこれが一番簡単です。todoAddButton関数内にtableView.reloadData()と書き込むだけです。

swift

1@IBAction func TodoAddButton(segue: UIStoryboardSegue) { 2 3     //segue.sourceとsegue.destinationはよく使います 4 //sourceは遷移元、destinationは遷移先です 5 guard let VC = segue.source as? AddController else { 6 fatalError("ViewController does not exist") 7 } 8 9 guard let text = VC.TodoTextField.text else { 10 fatalError() 11 } 12 todoItem.append(text) 13 14 UserDefaults.standard.set(todoItem, forKey: "TodoList" ) 15 16 tableView.reloadData()//<-ここ 17 }

注意すべき点をあえてあげるならばtodoItemtextを入れた後にreloadする、と言うことくらいでしょうか。でないと新しいデータが反映されませんからね。

投稿2018/09/16 06:28

編集2018/09/16 12:02
xAxis

総合スコア1349

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

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

kinu221

2018/09/16 11:00

ご回答ありがとうございます。 >guard let text = VC.textField.text else { →上記の箇所でValue of type 'ViewController' has no member 'textField'  と出ており、VC.textField.textを宣言していない為に出ていると思うのです が、ViewController.swift内に宣言すれば良いとの認識で合っていますでしょうか? お手数ですが、ご回答をお願い致します
xAxis

2018/09/16 11:23

エラーの読み方は合ってます。 これならキャストが抜けてるか、私のコードのtextFieldの部分をTodoTextFieldに書き換えてないかのどちらかですね。
xAxis

2018/09/16 11:24

というか回答を書き換えればいいですね。修正します。
kinu221

2018/09/16 11:46

ご回答ありがとうございます。 TodoTextField(UITextFieldも確認済み)に変更しても同様のエラーが表示されています。
xAxis

2018/09/16 12:00

自分のコードのキャスト間違ってました。失礼しました。修正します。
kinu221

2018/09/16 13:37

ご回答ありがとうございます。 エラーの方は解消できたのですが、動作確認するとAddボタンを押すと、フリーズし、Thread 1: signal SIGABRTエラーが表示されます。 segueの接続の方法にミスがあるのかだと思います。
kinu221

2018/09/16 13:54

上記エラーは解決しました。しかし、動作確認すると本題であるデータの反映がされません。tableView.reloadData()処理は記述してあります。
xAxis

2018/09/16 14:36

となるといくつか確認です。CustomCellを作ったりしてませんか?またCellのStyleはBasicになっていますか?あとTodoAddButton関数内にprint("add")とか書いてみてコンソールに表示されるか確認してもらえますか?
xAxis

2018/09/20 07:46

ベストアンサーもらっちゃいましたけども無事解決しましたかね?だったら良いのですけども。
kinu221

2018/09/24 12:29

いえ、まだ未解決です。TodoAddButton関数内にprint("add")を追加したらaddが表示されました。確認事項に記載されているtableView.datasource = selfが記載していなくて、追記したりしましたが、表示はされずThread 1: signal SIGABRTエラーがでるだけなのでお手上げ状態です。
xAxis

2018/09/24 13:14

ではもう少しトラブルシューティングしてみましょうか。 print("add")を含んだTodoAddButton関数とコンソール画面に表示されるreason以下を貼ってもらえますか?
kinu221

2018/09/25 12:42

申し訳ありませんがお願い致します。 コンソールの内容の画像を添付致しましたが、reasonが見当たらなく・・表示されているところ全てを貼りました。
xAxis

2018/09/26 01:58

では少々時間が経っていますし今どこまで出来ているのか分からないので追記でやったところまで書いたコードを貼ってもらえますか?
xAxis

2018/09/26 10:11

>>tyobigorouさん アシストありがとうございます。 本家stackoverflowで_BSMachErrorを調べたのですが本家ですら5件だったかな?しかヒットしなかったですねwこれはちょっと手間取るかもしれないなぁ。 コードを見る限りコードそのものには問題なさそうなんですよね。となるとStoryboardとかinfo.plistとか。 >>tyobigorouさんのコメント欄にある分を確認してみてください。 その確認が済んだら(もしあるなら)breakpointを全部削除して動かしてみてください。その後Storyboardを見直していきましょうか。 Storyboard上にある各ViewControllerのConnections Inspectrorで接続が間違っているものがないか見直してみてください。
kinu221

2018/09/27 11:29

viewDidLoadにtableview.dataSource = self、tableview.delegate = selfを追加するとアプリが起動できない時があります。 また、breakpointを全削除したり、Connections Inspectrorの確認をしました。 exitとaddを接続しているToDoAddButtonWithSegueにSegues initiated directly from view contorollers must have an identifierの警告が表示されています。 storybordのAddとexitの接続あたりが怪しいと思っていますが、Connections Inspectrorを確認すると接続は正しいので、どこに問題があるのか見当がつかない状態です。
xAxis

2018/09/27 15:09

> アプリが起動できない時があります こういう状態を見聞きしたことが今までないのでこれはちょっとお手上げな感じがありますね・・・。 最後の希望ですが>>tyobigorouさんのコメントから判断するにCellのStyleがBasicになってるか確認してみてください。 それと接続されているSegueを一旦全部切って再接続、というのは試されましたか?もし試されてないなら試してみてください。 これでダメだったら・・・コード量にもよりますが自分ならプロジェクトを新しく立ち上げて移植を考えます(個人で開発されているとか勉強中でアプリを作成してる、とかだったらの話限定ですけどね)。 あとはこちらでは解決まで至らなかった旨をしっかり書いてstackoverflowの日本語版に質問をしてみるとかですかね(ここでもあちらでもマルチポストは禁止事項なので)。 ただ、とにかく早く動く状態にしたい、とかなら自分なら迷わず移植します。
kinu221

2018/10/01 11:43

1から作り直すことで解決致しました。本当にここまでありがとうございます。様々なことを最後までアドバイスいただき、感謝しております。
guest

0

ViewControllerのviewDidLoadを以下に差し替えて、実行してみてください。
それで、TableViewに何も表示されなければ、xAxisさんが回答の中で指摘されている「確認事項」の部分が問題かと。

swift

1 override func viewDidLoad() { 2 super.viewDidLoad() 3 // Do any additional setup after loading the view, typically from a nib. 4 if UserDefaults.standard.object(forKey: "TodoList") != nil { 5 todoItem = UserDefaults.standard.object(forKey: "TodoList") as! [String] 6 } 7 todoItem = ["AAA", "BBB", "CCC"] 8 } 9

投稿2018/09/17 02:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/09/26 08:35

20180926時点でのソースコードを見させていただいて、質問とお願いがあります。 質問は、このソースコードでアプリを立ち上げた時に、表示されるTableViewに3つのセル"AAA","BBB","CCC"は表示されていますか? お願いは、上記を確認されたあとにViewDidLad内の、todoItem = ["AAA", "BBB", "CCC"]は削除しておいてください。
kinu221

2018/09/26 11:10

アプリを立ち上げた時、"AAA","BBB","CCC"は表示されませんでした。ViewDidLoad内の、todoItem = ["AAA", "BBB", "CCC"]は削除しておきました。
退会済みユーザー

退会済みユーザー

2018/09/28 08:45 編集

別件で偶然同じエラーに遭遇したので、まだ試していない場合、試してほしいことがあります。 アプリをシミュレータもしくは実機から一度削除したのち再度インストールしてみたらどうなるでしょうか? また、StoryboardEntryPointはviewControllerに入ってるのに、NavigationControllerの残骸のようなものがあるのも気になります。 基本的にはxAxisさんのおっしゃっているようにコードはコピペでいいのでプロジェクトを作り直しするのが早いと思います。 -- 念の為記入 -- 別件とは、任意のプロジェクトとは関係のないsimulatorのデータフォルダをfinderから削除したのち、そのプロジェクト上でデータの保存をかけると同様のエラーが発生したというものです。
kinu221

2018/10/01 11:41

アプリをシミュレータもしくは実機から一度削除したのち再度インストールし、1から作り直すと上手くいきました。 本当にありがとうございます。また、最後までお付き合いいただき、様々なアドバイスをありがとうございます。
guest

0

コメント欄に書くべきところを回答欄に書いてしまいましたごめんなさい。
20180926時点でのソースコードを見させていただいて、質問とお願いがあります。
質問は、このソースコードでアプリを立ち上げた時に、表示されるTableViewに3つのセル"AAA","BBB","CCC"は表示されていますか?
お願いは、上記を確認されたあとにViewDidLad内の、todoItem = ["AAA", "BBB", "CCC"]は削除しておいてください。

投稿2018/09/26 08:33

編集2018/09/26 08:34
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問