How to delete from tableview as well as sqlite3 using Swift - ios

I'm new to swift and sqlite3 and I need help on how to delete from tableview and sql db.
I tried to use reloadData() but it doesn't work. I tried to delete using tableView.deleteRows(at: [indexPath], with: .fade) but Im getting an error as I have a sql delete statement running before that. With this code provided below, Im successfully able to remove the item from the database, but it doesn't refresh the tableview. The way I got around to fixing it temporarily is perform a segue to previous screen upon successful removal of an item and when returned to the tableviewcontroller it would be removed.
import UIKit
class TableViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
let mainDelegate = UIApplication.shared.delegate as! AppDelegate
#IBOutlet var tableView: UITableView!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tableCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? SiteCell ?? SiteCell(style: .default, reuseIdentifier: "cell")
let rowNum = indexPath.row
tableCell.primaryLabel.text = mainDelegate.people[rowNum].name
tableCell.secondaryLabel.text = mainDelegate.people[rowNum].email
tableCell.myImageView.image = UIImage(named: mainDelegate.people[rowNum].avatar!)
tableCell.accessoryType = .disclosureIndicator
return tableCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mainDelegate.people.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let rowNum = indexPath.row
let details : String! = "Address: \(mainDelegate.people[rowNum].address!) \nPhone Num: \(mainDelegate.people[rowNum].phonenum!) \nEmail: \(mainDelegate.people[rowNum].email!) \nAge: \(mainDelegate.people[rowNum].age!) \nGender: \(mainDelegate.people[rowNum].gender!) \nDate of birth: \(mainDelegate.people[rowNum].dob!)"
let alertController = UIAlertController(title: mainDelegate.people[rowNum].name, message: details, preferredStyle: .alert
)
let cancelAction = UIAlertAction(title: "ok", style: .cancel, handler: nil)
print("TESTING ROW: \(mainDelegate.people[rowNum].id!)")
alertController.addAction(cancelAction)
present(alertController, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
var rowNum: Int = indexPath.row
if editingStyle == .delete {
print("Testing delete \(mainDelegate.people[rowNum].id!)")
print("\(indexPath.row)")
mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
print("\(indexPath)")
// tableView.deleteRows(at: [indexPath], with: .fade)
DispatchQueue.main.async{
self.tableView.reloadData()
}
// self.performSegue(withIdentifier: "DataToInfo", sender: self)
// let mainDelegate = UIApplication.shared.delegate as! AppDelegate
// mainDelegate.removeFromDatabase(person: mainDelegate.people[indexPath.row])
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mainDelegate.readDataFromDatabase()
}
removeFromDatabase method
func removeFromDatabase(id : Int){
var db : OpaquePointer? = nil
if sqlite3_open(self.databasePath, &db) == SQLITE_OK{
print("Successfully opened connection to database at \(self.databasePath)")
var deleteStatement : OpaquePointer? = nil
let deleteStatementString : String = "delete from entries where id=\(id)"
if sqlite3_prepare_v2(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK{
if sqlite3_step(deleteStatement) == SQLITE_DONE{
print("Deleted")
}
else{
print("Failed")
}
}else{
print("Couldn't prepare")
}
sqlite3_finalize(deleteStatement)
sqlite3_close(db)
}
}
Im trying to delete it from tableview as well as database. At one point I was trying to
mainDelegate.people.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
then running the removeFromDatabase, but it was giving me an error.

You should update your datasource. Try to refactor your commitEditing like this:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
var rowNum: Int = indexPath.row
if editingStyle == .delete {
print("Testing delete \(mainDelegate.people[rowNum].id!)")
print("\(indexPath.row)")
mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
print("\(indexPath)")
mainDelegate.readDataFromDatabase()
tableView.deleteRows(at: [indexPath], with: .fade)
}
}

Related

Table Cell Not Swiping

I'm developing a todo list app that links up with a Realm database, however when I'm trying to use the 'editingStyle' method which allows users to swipe on the cell to delete the data from the UI & the Realm database the cell doesn't swipe, the app has 2 screens, this method works fine on one the first one but it does not work on the other screen, the cell works fine it just won't swipe.
My code:
import UIKit
import RealmSwift
class CategoryViewController: UITableViewController {
var categories: Results<Category>?
let realm = try! Realm()
override func viewDidLoad() {
super.viewDidLoad()
loadCategories()
tableView.rowHeight = 60.0
}
//MARK: - Creating the table view cell
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories?.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath)
cell.textLabel?.text = categories?[indexPath.row].name ?? "No Categories Added Yet"
return cell
}
//MARK: - This will remove a category from the UI & the Realm database, this is a built in swift method
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let deleteAction = categories?[indexPath.row] {
do {
try realm.write({
realm.delete(deleteAction)
})
} catch {
print("Error deleting the cell \(error)")
}
}
}
tableView.deleteRows(at: [indexPath], with: .fade)
}
//MARK: - TableView Delegate Methods
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! TodoListViewController
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categories?[indexPath.row]
}
}
//MARK: - Add New Categories
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
var textField = UITextField()
let alert = UIAlertController(title: "Add New Category", message: "", preferredStyle: .alert)
let action = UIAlertAction(title: "Add", style: .default) { (action) in
// What happens when user clicks add button
let newCategory = Category()
newCategory.name = textField.text!
self.saveCategories(category: newCategory)
}
alert.addAction(action)
alert.addTextField { (field) in
textField = field
textField.placeholder = "Add a new category"
}
present(alert, animated: true, completion: nil)
}
//MARK: - Data Manipulation Methods
func saveCategories(category: Category) {
do {
try realm.write({
realm.add(category)
})
} catch {
print("Error saving category \(error)")
}
tableView.reloadData()
}
func loadCategories() {
categories = realm.objects(Category.self)
tableView.reloadData()
}
}
Add this:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
Your code seems correct. I think there's something wrong with realm.delete(_:) method which possibly throws an error which executes the catch block instead of deleting the row. Try to see if there is something wrong within the try block with a few print statements. And if all fails, try making the following changes
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let deleteAction = categories?[indexPath.row] {
do {
try realm.write({
realm.delete(deleteAction)
})
// New snippet
tableView.deleteRows(at: indexPath, with: .fade)
self.tableView.reloadData()
} catch {
print("Error deleting the cell \(error)")
}
}
}
}

Swipe to delete function insert including Core Data

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()
}
}
You are just removing the item from your local array, you need to persist the change after removing it.
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
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.
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()
}
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

didSelectRowAt is not being called for my table view

I want to make the transition from the UITableView cell to the view controller. My didSelectRowAt isn't working.
Here is code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var goals = [String]()
#IBAction func onAddTapped() {
let alert = UIAlertController(title: "Add Goal", message: nil, preferredStyle: .alert)
alert.addTextField { (dessertTF) in
dessertTF.placeholder = "Enter Goal"
}
let action = UIAlertAction(title: "Add", style: .default) { (_) in
guard let goal = alert.textFields?.first?.text else { return }
print(goal)
self.add(goal)
}
alert.addAction(action)
present(alert, animated: true)
}
func add(_ goal: String) {
let index = 0
goals.insert(goal, at: index)
let indexPath = IndexPath(row: index, section: 0)
tableView.insertRows(at: [indexPath], with: .left)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "segue", sender: self)
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return goals.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let dessert = goals[indexPath.row]
cell.textLabel?.text = goals
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
guard editingStyle == .delete else { return }
desserts.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
The problem is that you aren't creating your cells correctly.
Inside of your cellForRow function change
let cell = UITableViewCell()
to this:
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
Make sure that in your storyboard file, that you set the cell identifier to "Cell"

Adding swipe button in table view in swift

I have a simple table view showing a list of tasks. I want to show two buttons when user swipes on a cell. A delete button to delete the cell and Completed button to store the task in completed array. I am able to implement the delete button but no idea of showing a second button in the table cell. here is the code.
import UIKit
var taskArray = [String]()
var datesArray = [String]()
class ViewController: UIViewController, UITableViewDataSource
{
#IBOutlet weak var taskTableView: UITableView!
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)
cell.textLabel?.text = "\(indexPath.row + 1). \(taskArray[indexPath.row])"
cell.detailTextLabel?.text = datesArray[indexPath.row]
return cell
}
override func viewDidLoad()
{
super.viewDidLoad()
taskTableView.dataSource = self
let userDefaults = UserDefaults.standard
if let task = userDefaults.stringArray(forKey: "tasks") , let date = userDefaults.stringArray(forKey: "dates")
{
taskArray = task
datesArray = date
}
print(taskArray)
print(datesArray)
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
taskTableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
// remove the item from the data model
taskArray.remove(at: indexPath.row)
datesArray.remove(at: indexPath.row)
// delete the table view row
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
//function to come back from close button
#IBAction func close(segue: UIStoryboardSegue)
{
}
}
Swift 4.0
You can write below method of tableView to define custom swipe action.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .default, title: "Delete") { (action, indexPath) in
}
delete.backgroundColor = UIColor.red
let complete = UITableViewRowAction(style: .default, title: "Completed") { (action, indexPath) in
// Do you complete operation
}
complete.backgroundColor = UIColor.blue
return [delete, complete]
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
//self.isEditing = false
print("more button tapped")
}
more.backgroundColor = UIColor.lightGray
let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
//self.isEditing = false
print("favorite button tapped")
}
favorite.backgroundColor = UIColor.orange
let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
//self.isEditing = false
print("share button tapped")
}
share.backgroundColor = UIColor.blue
return [share, favorite, more]
}
First make this function return true
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
return true
}
it makes your cell editable , apple provides default deleting and editing options that you can use as like this :
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if(editingStyle == .delete)
{
myArray.remove(at: indexPath.item)
table.deleteRows(at: [indexPath], with: .automatic)
table.reloadData()
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
if(studentUser as? String == "Admin")
{
return .delete
}
else
{
return .none
}
}
or you can define your custom ones :
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let del = UITableViewRowAction(style: .normal, title: "Delete")
{
(action, index) in
let alert = FCAlertView()
alert.makeAlertTypeCaution()
alert.cornerRadius = 10
alert.delegate = self
alert.animateAlertInFromBottom = true
alert.animateAlertOutToTop = true
alert.bounceAnimations = true
alert.blurBackground = true
alert.dismissOnOutsideTouch = true
alert.showAlert(inView: self,
withTitle: "Title you want ",
withSubtitle: "Subtitle Comes here",
withCustomImage: nil,
withDoneButtonTitle:"OK" ,
andButtons:["Cancel"])
}
let edit = UITableViewRowAction(style: .default, title: "Edit")
{
(action, index) in
self.view.makeToast("Editing Coming soon...")
}
del.backgroundColor = AppColor.myNewRedColor
edit.backgroundColor = .lightGray
return [edit,del]
}
Swift 4.0
Add Delegate & DataSource
tableView.delegate = self
tableView.dataSource = self
Add DataSource func "canEditRowAt indexPath"
//MARK: - UITableViewDataSource
public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
Add Delegate func "editActionsForRowAt indexPath"
//MARK: - UITableViewDelegate
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
//Action edit
print("Action Edit...")
})
editAction.backgroundColor = UIColor.gray //Set button color
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
//Action delete
print("Action Delete...")
})
return [deleteAction, editAction]
}
I hope this helps.
As par your Requirement i have . created Demo for you.
Here is the Output,
When you press Delete element will be removed from Array and when you press Add Button element will be added to new Array.
Here is the link of Demo,
Tableview Demo with Swipable Add and Delete
Step 1:- Connect your Tableview datasource and delegate in Storyboard.
Step 2:- Write DataSource Methods of TableView.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "Preloaded Data"
} else {
return "Added Data to New Array"
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return arrPrelodedData.count
} else {
return arrAddNewData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "SwipeToDelete", for: indexPath) as? SwipeToDelete else {return UITableViewCell()}
if indexPath.section == 0{
cell.lblCellContent.text = arrPrelodedData[indexPath.row] }
else {
cell.lblCellContent.text = arrAddNewData[indexPath.row]
}
return cell
}
//With this we can edit UITableview ex. Swipe to Delete
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
if indexPath.section == 0 {
return true } else {
return false
}
}
//Select tableview Editing Style (insert and Delete)-> if custom icon than set None
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
//Delete Action 1) Create delete Action 2) Remove data with Indexpath 3) fetch data from coredata 4) delete tableview row 4) set delete button background color 5) return deleteAction in arry wether it is single
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
//Destructive Because we want to delete(destroy) the data from tableview
let deleteAction = UITableViewRowAction(style: .destructive, title: "DELETE") { (rowAction, indexpath) in
self.arrPrelodedData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexpath], with: .automatic)
}
let addAction = UITableViewRowAction(style: .normal, title: "ADD 1") { (rowAction, indexpath) in
self.arrAddNewData.append(self.arrPrelodedData[indexPath.row])
tableView.reloadSections(NSIndexSet(index: 1) as IndexSet, with: .none)
// tableView.reloadRows(at: [indexPath], with: .automatic)
}
deleteAction.backgroundColor = #colorLiteral(red: 1, green: 0.1491314173, blue: 0, alpha: 1)
addAction.backgroundColor = #colorLiteral(red: 0.9176470588, green: 0.662745098, blue: 0.2666666667, alpha: 1)
return [deleteAction,addAction]
}
}
I hope this answer will helpful for you.

Delete is not working in case of UITableview

MyTableviewController
var animalNameArray = ["cat","dog","lion"]
override func viewDidLoad() {
super.viewDidLoad()
tableview.delegate = self
tableview.dataSource = self
self.cancelButton.isEnabled = false
}
#IBAction func editButtonAtNavigationBar(_ sender: UIBarButtonItem) {
self.cancelButton.isEnabled = true
self.tableview.isEditing = !self.tableview.isEditing
sender.title = (self.tableview.isEditing) ? "Done" : "Edit"
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
animalNameArray.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let remove = UITableViewRowAction(style: .default, title: " ") { action, indexPath in
}
remove.backgroundColor = UIColor(patternImage: UIImage(named: "delete")!)
return [remove]
}
//conditional Rearranging the table view cells
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
}
I want to put the image (trash) instead of text, image is showing but the delete action is not happening when trying to delete the row. I don't know what I am doing wrong. How can I delete my tableview row? Can someone please help me? Thanks in advance.
You should remove the cell at the indexPath that is passed in editActionsForRowAt like this:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let remove = UITableViewRowAction(style: .default, title: " ") { action, indexPath in
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .left)
tableView.endUpdates()
}
remove.backgroundColor = UIColor(patternImage: UIImage(named: "delete")!)
return [remove]
}
It will delete the row but it won't be consistent with the data inside the array. You can also delete item from the array at the specific index and then call tableView.reloadData()
Once you delete row from tableview you need to reload rows
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let remove = UITableViewRowAction(style: .default, title: " ") { action, indexPath in
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .left)
self.tableView.reloadRows(at: [IndexPath], with: .fade)
}
remove.backgroundColor = UIColor(patternImage: UIImage(named: "delete")!)
return [remove]
}

Resources