I am trying to do something similar to Notes app and I am stuck with what i think is such a stupid thing. When i enter my app there is a add button to add new notes. I can then rename it and enter to a new view controller which consist of only title and textView on the whole screen. I use Codable and UserDefaults to save the data. Title is saving just fine, but whatever i type in textView and then come back to see all rows in tableView and i come back to that particular "note" all my typed text is gone.
This is my didSelectRowAt method
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Note") as? NoteViewController {
navigationController?.pushViewController(vc, animated: true)
vc.bodyText = note[indexPath.row].body
vc.titleText = note[indexPath.row].title
if note[indexPath.row].title == "New note" {
let ac = UIAlertController(title: "Rename note", message: "Please enter name for a new note", preferredStyle: .alert)
ac.addTextField()
ac.addAction(UIAlertAction(title: "Cancel", style: .default))
ac.addAction(UIAlertAction(title: "Rename", style: .default) { [unowned self, ac] _ in
let newName = ac.textFields![0]
note[indexPath.row].title = newName.text!
self.tableView.reloadData()
vc.viewDidLoad()
self.save()
})
present(ac, animated: true)
} else {
}
}
}
And my NoteViewController
class NoteViewController: UIViewController, UITextViewDelegate {
@IBOutlet var textView: UITextView!
var bodyText: String?
var titleText: String?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(image: .checkmark, style: .plain, target: self, action: #selector(saveNote))
title = titleText
textView.text = bodyText
}
And Save()
func save() {
let jsonEncoder = JSONEncoder()
if let savedData = try? jsonEncoder.encode(note) {
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "note")
} else {
print("failed to load data")
}
}
I tried changing my method didSelectRowAt by adding my save() to different places but it's only saving title.
CodePudding user response:
You may use a onSavingTap
closure in the NoteViewController to pass the data back to the main view controller.
class NoteViewController: UIViewController, UITextViewDelegate {
var onSavingTap: ((String) -> Void)?
@IBOutlet var textView: UITextView!
var bodyText: String?
var titleText: String?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(image: .checkmark, style: .plain, target: self, action: #selector(saveNote))
title = titleText
textView.text = bodyText
}
@objc func saveNote() {
onSavingTap?(textView.text ?? "")
}
}
then in the didSelectRow method you set the closure to update your data array as follows:
vc.onSavingTap = { [weak self] body in
self?.note[indexPath.row].body = body
self?.save()
}