前提・実現したいこと
SwiftでToDoアプリを作成しています。
「Done」ボタンをタップしたら(関数doneButtonTapped()
)各セルに表示されているデータをUserDefaultsに保存したいです。
(今回の場合、「パンを買う」「買い物」「3月16日」という文字列を保存したいです)
一番上のセルはTaskTitleTableViewCellというカスタムセルになっており、UITextFieldを設置しています。
現在、そのセルに設置したUITextFieldの値を取得する方法が分からずいます(2,3番目の値は取得できています)。
試しにセルのインスタンスを作成し、下記の通り試してみましたがnilとなり、エラーが発生してしまいます。
解決策としては、セルのUITextFieldの変化を監視し、何らかの方法でAddTaskViewControllerに通知をできればよいと考えているのですが、具体的にどのように実装すれば良いか見当がついておりません。
そこで、初歩的な質問で恐縮ですが、アドバイスいただけないでしょうか?
let cell = TaskTitleTableViewCell() print(cell.taskTitleTextField.text ?? "nil") //Fatal error: Unexpectedly found nil while unwrapping an Optional value
該当のソースコード
AddTaskViewController
1class AddTaskViewController: UIViewController { 2 3 @IBOutlet weak var largeTitleBackgroundView: UIView! 4 @IBOutlet weak var addTaskTableView: UITableView! 5 6 let titleLabelArray = ["", "カテゴリ", "日付"] 7 8 var detailLabelArray: [String] = ["", "個人", ""] 9 10 let datePicker = UIDatePicker() 11 12 let datePickerView = UIView() 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16 largeTitleBackgroundView.layer.addShadow() 17 initializeTableView() 18 detailLabelArray[2] = getToday() 19 } 20 21 override func viewWillAppear(_ animated: Bool) { 22 super.viewWillAppear(true) 23 addTaskTableView.reloadData() 24 } 25 26 private func getToday(format: String = "M月dd日") -> String { 27 let now = Date() 28 let formatter = DateFormatter() 29 formatter.dateFormat = format 30 return formatter.string(from: now) 31 } 32 33 private func initializeTableView() { 34 addTaskTableView.delegate = self 35 addTaskTableView.dataSource = self 36 addTaskTableView.backgroundColor = UIColor(red: 250, green: 250, blue: 250, alpha: 1.0) 37 addTaskTableView.register(UINib(nibName: "TaskTitleTableViewCell", bundle: nil), forCellReuseIdentifier: "TaskTitleTableViewCell") 38 } 39 40 @objc private func doneBarButtonTapped() -> String { 41 let formatter = DateFormatter() 42 formatter.dateFormat = "M月dd日" 43 detailLabelArray[2] = formatter.string(from: datePicker.date) 44 addTaskTableView.reloadData() 45 datePickerView.removeFromSuperview() 46 return formatter.string(from: datePicker.date) 47 } 48 49 private func showDatePicker() { 50 datePicker.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: datePicker.bounds.size.height) 51 datePicker.datePickerMode = UIDatePicker.Mode.date 52 datePicker.timeZone = NSTimeZone.local 53 datePicker.locale = NSLocale(localeIdentifier: "ja_JP") as Locale 54 datePickerView.frame = datePicker.bounds 55 let toolbar = UIToolbar() 56 let spaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) 57 let doneItem = UIBarButtonItem(title: "完了", style: .plain, target: self, action: #selector(doneBarButtonTapped)) 58 toolbar.setItems([spaceItem, doneItem], animated: true) 59 toolbar.sizeToFit() 60 datePickerView.addSubview(datePicker) 61 datePickerView.addSubview(toolbar) 62 view.addSubview(datePickerView) 63 let screenSize = UIScreen.main.bounds.size 64 datePickerView.frame.origin.y = screenSize.height 65 UIView.animate(withDuration: 0.3) { 66 self.datePickerView.frame.origin.y = screenSize.height - self.datePickerView.bounds.size.height 67 } 68 } 69 70 @IBAction func doneButtonTapped(_ sender: Any) { 71 print(detailLabelArray[1]) 72 print(detailLabelArray[2]) 73 let cell = TaskTitleTableViewCell() 74 print(cell.taskTitleTextField.text ?? "nil") 75 } 76 77 @IBAction func cancelButtonTapped(_ sender: Any) { 78 self.navigationController?.popViewController(animated: true) 79 } 80 81} 82 83extension AddTaskViewController: UITableViewDelegate, UITableViewDataSource { 84 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 85 return 3 86 } 87 88 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 89 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "addCell", for: indexPath) 90 let taskTitleCell = addTaskTableView.dequeueReusableCell(withIdentifier: "TaskTitleTableViewCell", for: indexPath) as! TaskTitleTableViewCell 91 if indexPath.section == 0 && indexPath.row == 0 { 92 print(taskTitleCell.taskTitleTextField.text ?? "aa") 93 return taskTitleCell 94 } 95 cell.textLabel?.text = titleLabelArray[indexPath.row] 96 cell.detailTextLabel?.text = detailLabelArray[indexPath.row] 97 return cell 98 } 99 100 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 101 return CGFloat.leastNormalMagnitude 102 } 103 104 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 105 addTaskTableView.deselectRow(at: indexPath, animated: true) 106 switch indexPath.row { 107 case 0: 108 return 109 case 1: 110 self.performSegue(withIdentifier: "toCategoryList", sender: nil) 111 case 2: 112 showDatePicker() 113 default: 114 return 115 } 116 } 117}
TaskTitleTableViewCell
1class TaskTitleTableViewCell: UITableViewCell, UITextFieldDelegate { 2 3 @IBOutlet weak var taskTitleTextField: UITextField! 4 5 override func awakeFromNib() { 6 super.awakeFromNib() 7 taskTitleTextField.delegate = self 8 } 9 10 override func setSelected(_ selected: Bool, animated: Bool) { 11 super.setSelected(selected, animated: animated) 12 } 13 14 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 15 textField.resignFirstResponder() 16 return true 17 } 18}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。