I have a TableView that displays a list of entries in the cells. The entries are stored in an array. The user enters in text for the entries in another view controller (modal), hits "Save", and after .reloadData()
, the new entry should append to the array and display in the TableView. The array lives in the HomeController
.
To pinpoint where the problem might be, I've tried appending some text in the HomeController
, then appending to the same array from the NotesController
. In the latter, when I print homeController.entryInput
, I'm expecting ["hello", "goodbye"]
. Instead, I only get ["goodbye"]
.
Also, when I click on "Save" in NotesController
a second time, I get ["goodbye"]
again instead of ["goodbye", "goodbye"]
. So it looks like the array gets overrided.
I've also tried hard coding items into the array, and they show up fine in the TableView. When I append an item from NotesController
, it appends to the array but doesn't show on the TableView, and when I add another item from the same ViewController, it overwrites the first item I appended rather than adding it as a new item.
HomeController:
class HomeController: UIViewController {
let tableView = UITableView()
var entryInput: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
}
func setupTableView() {
tableView.delegate = self
tableView.dataSource = self
self.entryInput.append("hello")
print(entryInput)
tableView.register(HomeCell.self, forCellReuseIdentifier: reuseIdentifier)
let height = view.frame.height
tableView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)
tableView.backgroundColor = .white
view.addSubview(tableView)
}
extension HomeController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return entryInput.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! HomeCell
cell.entryTextLabel.text = entryInput[indexPath.row]
return cell
}
NotesController:
class NotesController: UIViewController {
let homeController = HomeController()
...
let saveBtn = UIView().navigationBtn(text: "Save")
let homeController = HomeController()override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
saveBtn.addTarget(self, action: #selector(save(sender:)), for: .touchUpInside)
}
@objc func save(sender: UIButton) {
homeController.entryInput.append("goodbye")
homeController.tableView.reloadData()
print(homeController.entryInput)
dismiss(animated: true, completion: nil)
}
}
I've looked all around Stack Overflow and other websites about appending to arrays but for some reason can't seem to figure out why I can't append to an array in another class.
Because you have create new HomeController in NotesController that doesn't reference to your current HomeController.
class NotesController: UIViewController {
let homeController = HomeController()
}
When HomeController want to open NotesController. And NotesController want to communicate back to HomeController. You should pass HomeController reference to NotesController.
func routeToNotesController() {
let vc = NotesViewController()
vc.homeController = self
let nc = UINavigationController(rootViewController: vc)
present(nc, animated: true)
}
Answer your questions.
From the NotesController after save called. You're expecting ["hello","goodbye"] but you get ["goodbye"] instead.
When you add another item from NotesViewController, You're expecting ["goodbye", "goodbye"] but you get ["goodbye"] instead.
Here is the result.
My implementation.
class ListViewController: UITableViewController {
var entryInput: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "ListViewController"
tableView.backgroundColor = .white
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(add))
entryInput.append("hello")
tableView.reloadData()
}
@objc func add() {
let vc = InputViewController()
vc.listViewController = self
let nc = UINavigationController(rootViewController: vc)
present(nc, animated: true)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return entryInput.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = entryInput[indexPath.row]
return cell
}
}
class InputViewController: UIViewController {
weak var listViewController: ListViewController?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "InputViewController"
view.backgroundColor = .white
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(save))
}
@objc func save() {
listViewController?.entryInput.append("goodbye")
listViewController?.tableView.reloadData()
dismiss(animated: true)
}
}