0

I am trying to do a Simple Name List app. I have watched this video and copied everything ( https://www.youtube.com/watch?v=tP4OGvIRUC4 ) I now want to add a Swipe to delete function. It works the way I want it to work but when I close and reopen the app it will be like before. I tried different things but it did not work.

Anybody got any ideas?

Greets from Switzerland

Here is my ViewController:

import UIKit
import CoreData

class ViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!

    var people = [Person]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()

        do {
          let people = try PersistenceServce.context.fetch(fetchRequest)
            self.people = people
            self.tableView.reloadData()
        }catch{}
    }

    @IBAction func onPlusTapped() {
        let alert = UIAlertController(title: "Add name", message: nil, preferredStyle: .alert)
        alert.addTextField { (textField) in
            textField.placeholder = "Name"

        }
        let action = UIAlertAction(title: "Add", style: .default) { (_) in
            let name = alert.textFields!.first!.text!
            let person = Person(context: PersistenceServce.context)
            person.name = name
            PersistenceServce.saveContext()
            self.people.append(person)
            self.tableView.reloadData()

        }
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
         return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return people.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
        cell.textLabel?.text = people[indexPath.row].name
        return cell
    }
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

        guard editingStyle == UITableViewCell.EditingStyle.delete else { return }
        people.remove(at: indexPath.row)

        tableView.deleteRows(at: [indexPath], with: .automatic)
        self.tableView.reloadData()
    }
}
Keshu R.
  • 5,045
  • 1
  • 18
  • 38
noahae
  • 1
  • Hi, you only delete from array. More info here: https://stackoverflow.com/questions/37176861/how-to-swipe-delete-core-data-tableview-in-swift-2-0 – Zoltan Vinkler Jan 28 '20 at 15:39
  • Does this answer your question? [How to swipe delete core data tableview in Swift 2.0](https://stackoverflow.com/questions/37176861/how-to-swipe-delete-core-data-tableview-in-swift-2-0) – Zoltan Vinkler Jan 28 '20 at 15:41

5 Answers5

0

You are just removing the item from your local array, you need to persist the change after removing it.

javier rivarola
  • 500
  • 3
  • 6
0

when you reload apps your table take again data from fetch, where your deleted data stay. if you like delete data in fetch look at this topic Core Data Delete Object

Triker
  • 11
  • 4
0

This is how i have done it previously.

override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        // deleteAction, Call the deleteobject function, and then reload the data
        let deleteAction  = UITableViewRowAction(style: .default, title: DELETE_TITLE) { (rowAction, indexPath) in
            _ = deleteObject(name: self.dataSource[indexPath.row].name)
            self.tableview.reload()
        }
     return [deleteAction]
}


func deleteObject(name: String) -> Bool {
        let context = getContext()
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: ENTITY_NAME)
        fetchRequest.predicate = NSPredicate(format: formatStringForPredicate(oldListName: name))
        let objects = try! context.fetch(fetchRequest)
        for obj in objects {
            context.delete(obj as! NSManagedObject)
        }
        do {
            try context.save()
            return true
        } catch {
            return false
        }
    }

Note you may need to modify deleteObject function.

chirag90
  • 2,211
  • 1
  • 22
  • 37
0

First of all never call reloadData() right after insertRows(at or deleteRows(at because the insert/delete methods do update the UI.

To make the deletion persistent you have to delete the item in the context and save the context.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

    guard editingStyle == .delete else { return }
    let personToDelete = people.remove(at: indexPath.row)
    PersistenceServce.context.delete(personToDelete)
    tableView.deleteRows(at: [indexPath], with: .automatic)
    PersistenceServce.saveContext()
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks a lot. It works thanks to your lines of code. I'm very happy that so many good answers have come together which help me to better understand the topic Core Data and that in not even 24 hours. – noahae Jan 29 '20 at 12:13
0

In order to do anything with core data, it needs to load all necessary objects to memory, which is going to be accessed by your context, once you load the item you want to delete to the context all you need to do is simply context.delete(item) tableViewArray.remove(at: itemIndex in array) Then call the context.save() to save the changes you made to the persistence store