Data display error

I made a Tasks app. It runs completely fine without any error in code and the new task is also saved by clicking the save button but the newly added task does not display on the table view cell. First view controller for data display code:

import UIKit

class todolistVC: UIViewController , UITableViewDelegate , UITableViewDataSource {

@IBOutlet var table: UITableView!
@IBOutlet var label : UILabel!

private var tasks = [String]()


override func viewDidLoad() {
    super.viewDidLoad()
    
    self.title = "Tasks"
    table.delegate = self
    table.dataSource = self
    
    //for saving data even after closing app
    if !UserDefaults().bool(forKey: "setup"){
        UserDefaults().set(true, forKey: "setup")
        UserDefaults().set(0, forKey: "count")
    }
    updateTasks()
}

func updateTasks(){

    tasks.removeAll()

    guard let count = UserDefaults().value(forKey: "count") as? Int else{
        return
    }
    for x in 0..<count{
        if let task = UserDefaults().value(forKey: "task_\(x+1)") as? String{
            tasks.append(task)
        }
    }
    table.reloadData()
}

@IBAction func didTapAdd() {
    let vc = storyboard?.instantiateViewController(withIdentifier: "entry") as! entryVC
    vc.title = "New Task"
    vc.completion = {
        DispatchQueue.main.async {
          self.updateTasks()
            self.label.isHidden = true
            self.table.isHidden = false
       }}
    
    navigationController?.pushViewController(vc, animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return tasks.count
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell" , for : indexPath)
    cell.textLabel?.text = tasks[indexPath.row]
    return cell
}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    
    guard let vc = storyboard?.instantiateViewController(withIdentifier: "detail") as? DetailsVC else {
        return
    }
    vc.title = "Task"
    vc.task = tasks[indexPath.row]
    navigationController?.popToViewController(vc, animated: true)
    
}


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        tasks.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath],with: .automatic)
    }
}

} the entry view controller code:

import UIKit

class entryVC: UIViewController, UITextFieldDelegate{

@IBOutlet var field: UITextField!

var completion : (() -> Void)?

override func viewDidLoad() {
    super.viewDidLoad()
    field.delegate = self
    
   navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(saveTask))

}

 func textFieldShouldReturn(_ textField: UITextField)-> Bool {
    saveTask()
    return true
}
@objc func saveTask(){
    
    guard let text = field.text, !text.isEmpty else{
        return
    }
    guard let count = UserDefaults().value(forKey: "count") as? Int else {
        return
    }
    let newCount = count+1
    UserDefaults().set(newCount, forKey: "count")
    UserDefaults().set(text, forKey: "Task_\(newCount)")
    
    completion?()
    
    navigationController?.popViewController(animated: true)
    }

}

Answered by NisaFatima in 766286022

Can you please elaborate on these ways a little because am a beginner and I couldn't understand how to do these.

If I understand your code:

  • You don't call updateTasks() once you have added a task.
  • but you do it when you tap button, which is the reason it works here.

As you add in another class, you have several ways to do it:

  • Use notification between classes (the simplest IMHO)
  • use delegation to call updateTasks() from entryVC (note that class name should start with Uppercase : EntryVC)
  • pass a reference of TodolistVC instance when you transition to EntryVC
Accepted Answer

Can you please elaborate on these ways a little because am a beginner and I couldn't understand how to do these.

Data display error
 
 
Q