Now that we have our Company objects properly saved and presented in our application, it's time to allow the removal of these objects. In this lesson, we will implement the ability to swipe on a cell to present various actions such as Edit and Delete. Upon hitting the delete, we remove the object from our UITableView as well as deleting it from Core Data using our shared context.

Comments (26)
Athlee
5 years ago
Another great one, I does UICollectionView have a similar method to editActionForRowAt, or do you have to manually go through and make a pan gesture? Ive been waiting for a core data lecture forever!
Brian Voong
5 years ago
Athlee
5 years ago
Ill wait for you to do a tutorial on pods before I start really messing with them! You definitely have the best teaching style for me. I was able to create my first app and get seed funding by following your tutorials and being able to show my potential investors and interactive demo!
endodoug
5 years ago
So, what if I want to "pre-load" a few company.name/attributes into my user's tableView when they open the app after my update, and allow them to delete or edit them?
Brian Voong
5 years ago
endodoug
5 years ago
Oh wow, I never thought about checking for the version number. I know about checking for iOS versions, but I was unaware of build versions. Prepopulating my database is exactly what I'm talking about. I'll give it try. Thanks
edward
5 years ago
Hi Brain, I'm really enjoying these videos at the moment. Just one thing. I have put the context save code within the CoreDataManager and I am using a closure () -> () to pass in relevant functionality like when needing to dismiss the controller when adding a new company. However, how do I configure it so that I don't have to pass anything in for the closure, for example when calling save after deleting a row? currently my code still needs me to put in empty brackets rather then just being able to pass in nil or ignore it Also on a different note, having an option to edit our comments would be great if you have time as I seem to always find bad grammar and spelling in mine once I have submitted it. Anyhow, keep up the great work!
Brian Voong
5 years ago
edward
5 years ago
Thanks Brian, that is spot on.
simran5590
5 years ago
You can always use pastebin or gists untill than.
jethridge
5 years ago
I can't get over how helpful these courses are. They're worth so much more than what they're priced at. Not only do we learn how to develop a wide range of functions, but I find your techniques for incremental validation to be even more helpful. You have truly created a world class product with LBTA, Brian. For iOS, it's in a completely different league than Udemy, Lynda, etc. I have no doubt that if you continue with the Android tutorials, that they will be too. Thank you for all your help and hard work. It is truly appreciated.
Juanpablo Macias
5 years ago
Best investment I've ever made. It pays to get the best and learn how to do things right, saving time, effort, and money. Bravo to your success and effectiveness as a teacher!
Prabhdeep Singh Randhawa
5 years ago
hi Bryan, not sure if I m the only one facing this.when we continuously swipe and delete rows the app get crashed.
magic
5 years ago
I'm really enjoying my time here!!!!!!!!!!! Best Teacher Ever!
Christophe Bugnon
5 years ago
That's true !!
Juanpablo Macias
5 years ago
Would it be more difficult to achieve this edit/delete function in a collectionView? Is this why you went with tableView?
Christophe Bugnon
5 years ago
I think it's the same just you need to replace indexPath.row with IndexPath.item. Why do you want take an collectionView here ? We just had a list and in is nothing special. There you have answer when use collectionView and TableView. https://stackoverflow.com/questions/23078847/when-to-use-uicollectionview-instead-of-uitableview Here is an other answer from an user of Stack : "Here's my criteria: - If a UITableView can do it, use it - If a UITableView needs lots of code to do it or can't do it at all, use UICollectionView." I hope my answer has been helpful.
code_seeker
5 years ago
at 10:35 in the video, I had lines 31 and 32 backwards and it didn't work. When I reversed it and it looked like the video, it worked. Why is it important to remove the element from the companies array first before deleting the row in the tableView?
Brian Voong
5 years ago
code_seeker
5 years ago
Sorry for submitting three times, internet was slow and I impatiently clicked submit many times.
wolfy
5 years ago
Hi Brain, If the Company class is CoreData managed and should not be modified, can I still add class variables and methods?
Brian Voong
5 years ago
Haohong Zhao
4 years ago
Hi Brian, I meet the same bug you met: when I try to test the "swipe to delete" function, Xcode does not stop executing at the breakpoint inside the deleteAction closure, and even worse, the print statement inside that closure is not fired off. I quit Xcode and re-run my code, everything works fine again. This is probably a bug in Xcode.
thearley
4 years ago
After all records have been deleted, what was the rest of the code for the tableview footer message?
Brian Voong
4 years ago
janof
4 years ago
Hi Brian, I would like to implement the "swipe to delete" function, but it does not work as I expect. I need to add that into a UITableView controller witch is opened by Sliding Out Menu that I created according your awesome tutorial (https://www.letsbuildthatapp.com/course/Twitter-Slide-Out-Menu). I found out that Gesture recognizer for sliding the side menu is the guy that does not allow me to swipe to delete on my tableView cells. I am starting with swift, so I am not very good at this yet, that's why I would like to ask you for your help to resolve my issue.
Caroline Kuo
4 years ago
How did you rerun your application in the simulator?
Caroline Kuo
4 years ago
Shift Cmd h
frankusu
3 years ago
thanks !
Rosso1990
4 years ago
Hey Brian, first of all: I appreciate your lessons very much. They have helped me a lot during the last year. But I have the following problem. Deleting the entries works fine. I have gone a step further and added data to my CoreData Model. However, after deleting and saving the changes in context the file size of Documents&Data does not change at all. The app recognises that the data isn't there anymore, but the size remains the same. Any clues why that is so? Cheers Roland
Brian Voong
4 years ago
Rosso1990
4 years ago
My bad - maybe I should have mentioned that I download and save videos of about 15MB to 20MB size to core data. So I notice that when I go up to lets say 100MB Documents&File Size that that number changes when I add/delete new videos, but only by a fraction of its actual size. Thanks for the fast answer thou!
pawelcichonski
4 years ago
since the editActionsForRowAt is going away I wrote the edit & delete actions using trailingSwipeActionsConfigurationForRowAt, if there's a better way please share. It works but I don't know if (_, _, completionHandler) should be used that way: override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let delete = deleteAction(at: indexPath) let edit = editAction(at: indexPath) return UISwipeActionsConfiguration(actions: [delete, edit]) } //delete func deleteAction(at indexPath: IndexPath) -> UIContextualAction { let delete = UIContextualAction(style: .destructive, title: "Delete") { (_, _, completionHandler) in let company = self.companies[indexPath.row] self.companies.remove(at: indexPath.row) self.tableView.deleteRows(at: [indexPath], with: .automatic) let context = CoreDataManager.shared.persistentContainer.viewContext context.delete(company) do { try context.save() } catch let deleteErr { print("Failed to delete company", deleteErr) } completionHandler(true) } delete.backgroundColor = .mainRed return delete } //edit func editAction(at indexPath: IndexPath) -> UIContextualAction { let editAction = UIContextualAction(style: .normal, title: "Edit") { (_, _, completionHandler) in let editCompanyController = CreateCompanyController() editCompanyController.company = self.companies[indexPath.row] let layout = CustomNavigationController(rootViewController: editCompanyController) editCompanyController.delegate = self self.present(layout, animated: true, completion: nil) completionHandler(true) } editAction.backgroundColor = .black return editAction }
Malikov_Vladimir
3 years ago
thank you!
frankusu
3 years ago
Hey pawelcichonski Thanks so much! Do you know what completionHandler(true) does? It works without it so I don't know why we need it.
johnicode101
3 years ago
hey i used the code u provided but im getting an error saying Value of type 'CreateCompanyController' has no member 'company'" and im not sure what it is
Dino32
3 years ago
Hi frankusu, I'm not sure if you still need it. The completionHandler(true) is needs to be in code since it gives you an ability to slide back the row once you hit the delete or edit button.
MaxApp
4 years ago
Hello Brian, a quick question about this code below. When you are tapping the reset are you delete all the data or just the companies? Are you deleting the employees also or no. If yes, please explain to me why the employees get deleted when you delete the company. Thank you @objc private func handleReset() { print("Attempting to delete all core data objects") let context = CoreDataManager.shared.persistentContainer.viewContext let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: Company.fetchRequest()) do { try context.execute(batchDeleteRequest) var indexPathsToRemove = [IndexPath]() for (index, _) in companies.enumerated() { let indexPath = IndexPath(row: index, section: 0) indexPathsToRemove.append(indexPath) } companies.removeAll() tableView.deleteRows(at: indexPathsToRemove, with: .left) } catch { print("Failed to delete objects from Core Data:", error) } }
Brian Voong
4 years ago
MaxApp
4 years ago
Oh okay, and sorry for the question. I know this is an old course.
Brian Voong
4 years ago
MaxApp
4 years ago
Last thing, you just updated the website. Did you just change the client side or you wrote it with Sails. I'm going start on the sails course very soon.
Brian Voong
4 years ago
iosmkarim
3 years ago
For deleting while using following code always first row inside the core Data is popping up again "context.delete(self.companies[indexPath.row])" but while using following code it's working fine tho "company = self.companies[indexPath.row]" same thing "let company = self.companies[indexPath.row]" "context.delete(company)" Any idea what might be the reason?
frankusu
3 years ago
For those using iOS 13 and using trailingSwipAction and UIContextualAction here's a post I found https://chariotsolutions.com/blog/post/uitableview-swipe-actions-in-ios-11/
Alex Herrera
3 years ago
Hello Brian. Can you help us to solve / update the deleteAction and editAction in Swift11? Under "ContextualActions"? I am not able to move on in the app dev course... Thank you!
Alex Herrera
3 years ago
My bad: Swift 5
jademagnum
3 years ago
Hey Brian, noticed in Xcode 11.3.1 that there is a way to link up Core Data with iCloud. Would be neat to add that onto this tutorial.
Eugeneberezin
3 years ago
So for those who were confused tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? being deprecated and the Xcode would ask for UIContextualAction, here what worked for me: func delete(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction { let company = companies[indexPath.row] let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, _) in self.companies.remove(at: indexPath.row) self.tableView.deleteRows(at: [indexPath], with: .bottom) // delete the company from Core Data let context = CoreDataManager.shared.persistentContainer.viewContext context.delete(company) do { try context.save() } catch let saveErr { print("Failed to delete company:", saveErr) } } return action } func edit(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction { let action = UIContextualAction(style: .normal, title: "Edit") { (action, view, escaping) in print("Edit") } return action } override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let delete = self.delete(forRowAtIndexPath: indexPath) let edit = self.edit(forRowAtIndexPath: indexPath) let swipe = UISwipeActionsConfiguration(actions: [delete, edit]) return swipe } Note that when it's time to edit, you would need to edit the method edit.
Manish Prakharan
2 years ago
Hey Great! Thanks For the corrections.
Matthew Easton
3 years ago
Hey Brian, for some reason when i copy and paste company from line 16: let company = self.companies [indexPath.row] just like in the video, i get an error saying "use of unresolved identifier 'company'" Could this be because the UITableViewRowAction is deprecated? Any help appreciated.
Matthew Easton
3 years ago
Hey Brian, i think I'm going to give up on this tutorial list as i don't want to have to keep finding solutions to deprecated problems this early on into learning iOS. Although i would like to keep learning iOS through one of your courses as your Kotlin Messenger tutorial playlist impressed me. Which one of your courses is the most up-to-date/ you would recommend? Alternatively, when do you plan on releasing your SwiftUI version of this course that you previously mentioned? Thanks
iosmkarim
3 years ago
//Hope below code will be helpful for "delete" and "edit" action override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { //Delete Action let deleteItem = UIContextualAction(style: .destructive, title: "delete") { (action, view, bool) in let company = self.companies[indexPath.row] //update array self.companies.remove(at: indexPath.row) //update table view self.tableView.deleteRows(at: [indexPath], with: .automatic) //update core data let context = CoreDataManager.shared.persistentContainer.viewContext context.delete(company) do { try context.save() }catch let saveErr { print("failed to delete company", saveErr) } } //Edit Action let editItem = UIContextualAction(style: .normal, title: "Edit") { (action, view, bool) in print("edit") } let swipeAction = UISwipeActionsConfiguration(actions: [deleteItem, editItem]) return swipeAction }
arroyot24
3 years ago
Thanks! Perfect correction for me to update the video code. Great.
HELP & SUPPORT