Reputation: 97
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
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
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