前提・実現したいこと
swift4で入力画面(A)で記入した内容を別画面(B)tableViewに新たな行として追加したいです。
今の所セグエで入力画面完了後にtableViewの画面Bに遷移しています。
入力画面から送るデータは構造体で下記の様になります。これが一つの行のまとまりで、
このセットを何行か表示していきたいです。
struct NewData { var title :String var memo :UITextView var img :UIImageView var lebel :String }
完了ボタン押下後に実行される関数です。↓
上記の構造体をセグエで渡しています。
@IBAction func completeButtonAction(_ sender: Any) { performSegue(withIdentifier: "didCompleteAddTask", sender: nil) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "didCompleteAddTask" { let listview:ListViewController = (segue.destination as! ListViewController) let newData:NewData = NewData(title:title memo:textView, img :selectedImage, lebel: selectedLebel) listview.oldData.append(newData)
↑上記にあるlistview:ListViewControllerは画面tableviewを表示するコントローラーです。
そのクラスにはプロパティとして構造体入力されたデータを格納する配列を宣言しています。
さらに表示するたtableviewのメソッドもあります。
class ListViewController: UIViewController ,UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! //タスク追加画面から受け取るためのパラメーター var oldData = [NewData]() 〜〜〜〜〜省略〜〜〜〜〜〜〜 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //print(newData.title) return self.oldData.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) //print(indexPath.row) //表示内容 cell.textLabel?.text = oldData[indexPath.row].title cell.detailTextLabel?.text = oldData[indexPath.row].memo.text cell.imageView?.image = oldData[indexPath.row].img.image return cell }
長くなりましたがこれからつまずいているポイントです。
発生している問題
構造体を格納するためにプロパティで配列を作りどんどんappendで追加して表示させたいのです。
しかし、はじめに追加した一つのみ表示されるのですが、二つめ以降は追加されず置き換わってしまいます。
一つめ追加後、もう一度追加画面に移動し完了ボタンを押すと viewdidloadが読み込まれプロパティに保存していたものが消えてしまっている様な気がします。それともappendの仕方が間違っているのでしょうか?
ただしテーブルビューに一つだけ追加された行を押下し詳細画面(c)に行き戻ると残っています。
(ナビゲーションバーを利用。戻るとviewdidloadは実行されずviewwillappearが実行される)
追加画面(画面B)でキャンセルボタンを押すとセグエでtableview画面に戻る様にもしていますが
その時も追加していたものが無くなっています。
===============================
長くなりましたが下記の3つが疑問です。
①セグエで戻るとviewdidLoadでリセットされしまうのでしょうか?
②appendの使い方は正しいでしょうか?
③どのようにして画面テーブルビュー一覧画面に追加して行ける様になるのか(最終的に実現したいこと)
④realmでデータを保存し呼び出す様にしないとやはりできないのでしょうか?
swiftを勉強し始めて3か月のど素人です優しい言葉でお願いします。
≦(._.)≧ ペコ
念の為関係するファイルを記載します。
都合上関係のないコメントやスペースが入っています。
addTaskViewController.swift
import UIKit //構造体 struct NewData { var title :String var memo :UITextView var img :UIImageView var lebel :String } var willAddData = [NewData]() class addTaskViewController: UIViewController ,UITextViewDelegate,UIPickerViewDelegate,UIPickerViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate{ @IBOutlet weak var memoPlaceHolder: UILabel! //以下4つがリストに送る値 @IBOutlet weak var textView: UITextView! @IBOutlet weak var lebelPicker: UIPickerView! @IBOutlet weak var selectedImage: UIImageView! var selectedLebel :String = "" var lebelDataList = ["1級","2級","3級"] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. //self.navigationController?.setNavigationBarHidden(true, animated: false) textView.delegate = self } //ナビゲーションバーの非表示 override func viewWillAppear(_ animated: Bool) { self.navigationController?.setNavigationBarHidden(true, animated: false) } override func viewDidDisappear(_ animated: Bool) { self.navigationController?.setNavigationBarHidden(false, animated: false) } /**********************************************/ override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /**********************************************/ //テキストフィールドをクリックした時 func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { memoPlaceHolder.isHidden = true //print("クリックされました") return true } //テキストフィールドから外れた時,空だったら表示。 func textViewDidEndEditing(_ textView: UITextView) { if textView.text.isEmpty { memoPlaceHolder.text = "ここにメモを残せます。" memoPlaceHolder.isHidden = false } else { self.textView.text = textView.text } } /*********************************************************/ //UIPickerViewの設定 func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return lebelDataList.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return lebelDataList[row] } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { self.selectedLebel = lebelDataList[row] } //画像を追加 @IBAction func addImageButtonAction(_ sender: Any) { print("クリックされた") let controller: UIAlertController = UIAlertController(title:"", message: "どの方法で写真を読み込みますか?", preferredStyle: UIAlertControllerStyle.actionSheet) //1つ目の選択肢 controller.addAction(UIAlertAction(title: "撮影する", style: UIAlertActionStyle.default, handler: { (hoge) in self.selectedCamera() })) //2つ目の選択肢 controller.addAction(UIAlertAction(title: "カメラロールから読み込む", style: UIAlertActionStyle.default, handler: { (action) in self.selectedLibrary() })) //3つ目キャンセル controller.addAction(UIAlertAction(title: "キャンセル", style: UIAlertActionStyle.cancel, handler: nil)) //UIControllerを表示 self.present(controller, animated: true, completion: nil) } func selectedCamera(){ //カメラが利用できるならば if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) { //インスタンスを作成 let picker :UIImagePickerController = UIImagePickerController() picker.sourceType = UIImagePickerControllerSourceType.camera picker.delegate = self present(picker, animated: true, completion: nil) } } func selectedLibrary() { if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) { let picker : UIImagePickerController = UIImagePickerController () picker.sourceType = UIImagePickerControllerSourceType.photoLibrary picker.delegate = self present(picker, animated: true, completion: nil) } } /***************************/ //画像の表示 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { selectedImage.image = info[UIImagePickerControllerOriginalImage] as? UIImage dismiss(animated: true, completion: nil) } /***************************/ //完了ボタン押下後のセグエ(セルに課題を追加する) @IBAction func completeButtonAction(_ sender: Any) { performSegue(withIdentifier: "didCompleteAddTask", sender: nil) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "didCompleteAddTask" { let listview:ListViewController = (segue.destination as! ListViewController) let newData:NewData = NewData(title:"未定", memo:textView, img :selectedImage, lebel: selectedLebel) listview.oldData.append(newData) } }
2つめListViewController.swift
import UIKit class ListViewController: UIViewController ,UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var tableView: UITableView! //タスク追加画面から受け取るためのパラメーター // var newData:NewData! var oldData = [NewData]() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. tableView.delegate = self tableView.dataSource = self } override func viewWillAppear(_ animated: Bool) { self.navigationItem.hidesBackButton = true } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //print(newData.title) return self.oldData.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = oldData[indexPath.row].title cell.detailTextLabel?.text = oldData[indexPath.row].memo.text cell.imageView?.image = oldData[indexPath.row].img.image return cell }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/15 10:54