user11640506
user11640506

Reputation: 97

How to reload table view data source automatically

Iam building a simple todo app for iOS using core data.I was able to store and fetch data success fully from core data.When the user clicks add button alert with UItextfield will be displayed and iff user clicks save then data will be saved and automatically added to table view.But I was unable to add the fetched data automatically to the table view.The fetched data is added to the table view only when I scroll the table view.

import UIKit
import CoreData


let appdelinstance = UIApplication.shared.delegate as! AppDelegate
class ViewController: UIViewController{

    var task: String!

    var taskarray: [Task] = [Task]()

    @IBOutlet weak var tasktableview: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tasktableview.delegate = self
        tasktableview.dataSource = self
        getTask()

    }

    override func viewWillAppear(_ animated: Bool) {

    }


    @IBAction func addnotebtnclicked(_ sender: Any) {

        let alert = UIAlertController(title: "Add new Task", message: "Enter your task ", preferredStyle: .alert)

        let alertaction = UIAlertAction(title: "Save", style: .default) { (UIAlertAction) in
            let textfield = alert.textFields![0] as UITextField
            self.task = textfield.text
            print(self.task!)
            self.save(taskdata: self.task)
            self.getTask()
            self.tasktableview.reloadData()

        }

        alert.addTextField { (UITextField) in
            UITextField.placeholder = "Task here"
        }

        alert.addAction(alertaction)

        self.present(alert,animated: true)

    }

}    

extension ViewController:UITableViewDataSource,UITableViewDelegate
{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return taskarray.count
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "taskcell", for: indexPath)

        let taskdata = taskarray[indexPath.row]

        cell.textLabel?.text = taskdata.taskcontent!

        return cell
     }

    func save(taskdata: String?)
    {
        let managedcontext = appdelinstance.persistentContainer.viewContext

        let task = Task(context:managedcontext)

        task.taskcontent = taskdata!

        do
        {
            try managedcontext.save()
            print("Save success")
        }

        catch
        {
            print("ERROR \(error.localizedDescription)")
        }
    }



    func getTask()
    {
        let managedcontext = appdelinstance.persistentContainer.viewContext

        let fetchrequest = NSFetchRequest<Task>(entityName: "Task")

        do
        {
           taskarray =  try managedcontext.fetch(fetchrequest)
           print(taskarray[0].taskcontent!)
           tasktableview.reloadData()
        }

        catch
        {
            print("ERROR WHILE FETCHING \(error.localizedDescription)")
        }
    }               
}

Upvotes: 1

Views: 752

Answers (2)

vadian
vadian

Reputation: 285039

There is no reason to refetch the data after saving.

Replace the alert action with – by the way the closure parameter is not a type –

 let alertaction = UIAlertAction(title: "Save", style: .default) { action in
    let textfield = alert.textFields![0] as UITextField
    self.task = textfield.text
    print(self.task!)
    self.save(taskdata: self.task)
}

In save add the created Task object to the data source array and insert a row

func save(taskdata: String?)
{
    let managedcontext = appdelinstance.persistentContainer.viewContext
    let task = Task(context:managedcontext)
    task.taskcontent = taskdata!

    do
    {
        try managedcontext.save()
        let insertionIndex = taskarray.count
        taskarray.append(task)
        DispatchQueue.main.async {
            let indexPath = IndexPath(row: insertionIndex, section: 0)
            tasktableview.insertRows(at: [indexPath], with: .automatic)
        }
        print("Save success")
    } catch {
        print("ERROR \(error.localizedDescription)")
    }
}

Upvotes: 1

Ankur Lahiry
Ankur Lahiry

Reputation: 2315

You aren't reloading data in main thread. You should have call the getTask() of UIAlertAction in main thread

let alertaction = UIAlertAction(title: "Save", style: .default) { (UIAlertAction) in
            let textfield = alert.textFields![0] as UITextField
            self.task = textfield.text
            print(self.task!)
            self.save(taskdata: self.task)

            DispatchQueue.main.async {
                self.getTask()
            }


        }

Upvotes: 1

Related Questions