Swift: How to delete with Edit button and deactivate swipe to delete? - uitableview

I have added an edit button with an IBAction to the navigation bar:
#IBOutlet weak var editButton: UIBarButtonItem!
#IBAction func doEdit(sender: AnyObject) {
if (self.tableView.editing) {
editButton.title = "Edit"
self.tableView.setEditing(false, animated: true)
} else {
editButton.title = "Done"
self.tableView.setEditing(true, animated: true)
}
}
For removing cells I have
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
arr.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
Unfortunately this also activates swipe to delete. How can I remove cells without implementing swip to delete?

The solution (from this answer), translated into Swift:
override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
if (self.tableView.editing) {
return UITableViewCellEditingStyle.Delete;
}
return UITableViewCellEditingStyle.None;
}

Here's the working code:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
arr.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
if (self.tableView.editing) {
return UITableViewCellEditingStyle.Delete
}
return UITableViewCellEditingStyle.None
}

Swift-4
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
// delete item at indexPath
}
let action2 = UITableViewRowAction(style: .normal, title: "action2") { (action, indexPath) in
// action2 item at indexPath
}
return [delete, action2]
}

Related

Allow UITableView to reorder, but not delete in edit mode, and enable swipe to delete anyway

I have a UITableView (iOS 9)
I have implemented two actions with swipe (one is delete)
I have an Edit button to enable edit mode (to reorder the rows)
For that, I implemented
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated:animated)
if (!isInSwipeDeleteMode) {
if (self.tableView.editing) {
metAJourPersonnes()
tableView.reloadData()
}
else {
tableView.reloadData()
}
}
}
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
if (indexPath.row < personnes.count) {
return true
} else {
return false
}
}
override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
let pers = personnes[sourceIndexPath.row]
personnes.removeAtIndex(sourceIndexPath.row)
if (destinationIndexPath.row < personnes.count)
{
personnes.insert(pers, atIndex: destinationIndexPath.row)
} else {
personnes.append(pers)
}
tableView.reloadData()
}
override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
if (indexPath.row < personnes.count) {
return .Delete
} else {
return .None
}
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let deleteClosure = { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
print("Delete closure called")
self.tableView(tableView, commitEditingStyle: .Delete, forRowAtIndexPath: indexPath)
}
let modifyClosure = { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
print("More closure called")
self.performSegueWithIdentifier("modifPersonne", sender: indexPath)
}
let deleteAction = UITableViewRowAction(style: .Default, title: "Supprimer", handler: deleteClosure)
let modifyAction = UITableViewRowAction(style: .Normal, title: "Modifier", handler: modifyClosure)
return [deleteAction, modifyAction]
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
switch editingStyle {
case .Delete:
// Delete in the coreData base
personnes.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
default: break
}
}
Everything is working fine, but I want the edit mode just working for reordering. I don't want the red minus sign to appear, but I want to keep the swipe actions.
Is this possible? It seems that disabling delete in edit mode does disable the swipe to delete gesture.
I believe the only thing you need to change in your code is the editingStyleForRowAtIndexPath function. You only return .Delete if the table view is not in editing mode.
This way swipe-to-delete still works (not in editing mode), and when you do switch to editing mode, the row can't be deleted.

editActionsForRowAtIndexPath is not working

I'm developing a small app using Swift, an UITableView to show custom cells, and then I would like to swipe to edit to do that I use the following code :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! BasicCell
cell.Name.text = contacts[indexPath.row].Name
cell.Phone.text = contacts[indexPath.row].Phone
cell.ProfilPic.load(contacts[indexPath.row].ProfilPic!)
cell.ProfilPic.layer.masksToBounds = true
cell.ProfilPic.layer.cornerRadius = CGRectGetWidth(cell.ProfilPic.frame)/2.0
return cell
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?{
let delete = UITableViewRowAction(style: .Normal, title: "Delete") { action, index in
print("delete")
}
let done = UITableViewRowAction(style: .Default, title: "Done") { action, index in
print("done")
}
return [delete, done]
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// the cells you would like the actions to appear needs to be editable
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
// you need to implement this method too or you can't swipe to display the actions
}
the problem is when I swipe a cell, buttons are not showing :

tableview edit mode does not allow delete and/or menu: what is missing?

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var items = ["foo", "bar", "baz", "mamma mia"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.editing = true
navigationItem.leftBarButtonItem = editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(table1: UITableView,
numberOfRowsInSection section: Int)
-> Int {
return self.items.count
}
// `UITableViewCell`s for each section and row
func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
let item = self.items[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = item
return cell
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
print ("at editing style")
if editingStyle == .Delete {
print ("delete at row: \(indexPath.row)")
}
if editingStyle == .Insert {
print ("insert at row: \(indexPath.row)")
}
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// print ("at can edit row: \(indexPath.row)")
return true
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
}
}
why is the menu/delete buttons not appearing?
if (when) they do appear, are they processed at commitEditingStyle?
Implement this method:
func tableView(tableView: UITableView!, editingStyleForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCellEditingStyle {
return .Delete
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let shareAction = UITableViewRowAction(style: .Normal, title: "Share") { (action, indexPath) -> Void in
// tableView.editing = false
print("shareAction")
}
let deleteAction = UITableViewRowAction(style: .Normal, title: "Delete") { (action, indexPath) -> Void in
// tableView.editing = false
print("deleteAction")
}
// shareAction.backgroundColor = UIColor.grayColor()
return [deleteAction, shareAction]
}

delete a row in table view in swift

I am trying to delete a row in table view. I have implemented the required methods but when i am swiping the row horizontally no delete button is coming. I have searched and I have found the same solution everywhere but it is not working in my case. I don't know where i am making mistake. Can anyone help me please?
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
if editingStyle == .Delete
{
dataHandler.deletePeripheral(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
If below coding is helpful for you,i will be happy
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
if editingStyle == .Delete
{
yourArray.removeAtIndex(indexPath.row)
self.tableView.reloadData()
}
}
SWIFT 3.0
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
yourArray.remove(at: indexPath.row)
tblDltRow.reloadData()
}
}
You have to refresh the table.
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
self.tableView.beginUpdates()
self.arrayData.removeObjectAtIndex(indexPath.row) // also remove an array object if exists.
self.tableView.deleteRowsAtIndexPaths(NSArray(object: NSIndexPath(forRow: indexPath.row, inSection: 2)), withRowAnimation: UITableViewRowAnimation.Left)
self.tableView.endUpdates()
}
Apply Autolayout Constraints to table view. The delete button is there but not displaying because of no auto layout
I struggled with this as well but finally found out a solution - I am running XCode 8.3.2. A lot of the answers I read were for older versions of XCode / Swift and many were for Objective-C.
The solution I found was to use the 'editActionsForRowAt' tool for UITableViews. Note: Everything else I read kept pointing me towards the 'commit editingStyle' tool for UITableView, but I could never get it to work. Using editActionsForRowAt worked perfectly for me.
NOTE: 'postData' is the name of the Array that I added data to.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, IndexPath) in
// Remove item from the array
postData.remove(at: IndexPath.row)
// Delete the row from the table view
tableView.deleteRows(at: [IndexPath as IndexPath], with: .fade)
})
// set DeleteAction Button to RED (this line is optional - it simply allows you to change the color of the Delete button - remove it if you wish)
deleteAction.backgroundColor = UIColor.red
return [deleteAction]
}
I also have some code to add an 'EDIT button' alongside the Delete button:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, IndexPath) in
//print("Edit tapped")
})
// Set EditAction button to blue (this line is not mandatory - it just sets the color of the Edit box to blue)
editAction.backgroundColor = UIColor.blue
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, IndexPath) in
//print("Delete tapped")
// Remove item from the array
postData.remove(at: IndexPath.row)
// Delete the row from the table view
tableView.deleteRows(at: [IndexPath as IndexPath], with: .fade)
})
// set DeleteAction Button to RED (this line isn't mandatory - it just sets the color of the Delete box)
deleteAction.backgroundColor = UIColor.green
return [editAction, deleteAction]
}
EDIT: fixed format so code showed up in the grey box :)
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
if editingStyle == UITableViewCellEditingStyle.Delete {
numbers.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
for swift 3
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete {
dataHandler.deletePeripheral(indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
// - OR -
// mTableView.reloadData() //mTableView is an outlet for the tableView
}
}
i know what prob you are having . I think you just check your table constraints they may be wrong just recheck your auto layout constraints
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
yourArray.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
if editingStyle == .Delete
{
carsArray.removeAtIndex(indexPath.row)
self.tableView.reloadData()
}
}

Add swipe to delete UITableViewCell

I am making a CheckList application with a UITableView. I was wondering how to add a swipe to delete a UITableViewCell.
This is my ViewController.swift:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
var tableView: UITableView!
var textField: UITextField!
var tableViewData:Array<String> = []
// Define Colors
let lightColor: UIColor = UIColor(red: 0.996, green: 0.467, blue: 0.224, alpha: 1)
let medColor: UIColor = UIColor(red: 0.973, green: 0.388, blue: 0.173, alpha: 1)
let darkColor: UIColor = UIColor(red: 0.800, green: 0.263, blue: 0.106, alpha: 1)
let greenColor: UIColor = UIColor(red: 0.251, green: 0.831, blue: 0.494, alpha: 1)
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Custom initialization
}
override func viewDidLoad() {
super.viewDidLoad()
//Set up table view
self.tableView = UITableView(frame: CGRectMake(0, 100, self.view.bounds.size.width, self.view.bounds.size.height-100), style: UITableViewStyle.Plain)
self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "myCell")
self.tableView.backgroundColor = darkColor
//self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
self.tableView.delegate = self
self.tableView.dataSource = self
self.view.addSubview(self.tableView)
//Set up text field
self.textField = UITextField(frame: CGRectMake(0, 0, self.view.bounds.size.width, 100))
self.textField.backgroundColor = lightColor
self.textField.font = UIFont(name: "AvenirNext-Bold", size: 26)
self.textField.delegate = self
self.view.addSubview(self.textField)
}
//Table View Delegate
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return tableViewData.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var myNewCell: MyTableViewCell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as MyTableViewCell
myNewCell.text = self.tableViewData[indexPath.row]
return myNewCell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
let mySelectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)
//Colors
mySelectedCell.detailTextLabel.textColor = UIColor.whiteColor()
mySelectedCell.tintColor = UIColor.whiteColor()
//Setup Details / Date
let myDate:NSDate = NSDate()
var myDateFormatter:NSDateFormatter = NSDateFormatter()
myDateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
mySelectedCell.detailTextLabel.text = myDateFormatter.stringFromDate(myDate)
mySelectedCell.accessoryType = UITableViewCellAccessoryType.Checkmark
mySelectedCell.backgroundColor = greenColor
}
override func prefersStatusBarHidden() -> Bool {
return true
}
//Text Field Delegate
func textFieldShouldReturn(textField: UITextField!) -> Bool {
tableViewData.append(textField.text)
textField.text = ""
self.tableView.reloadData()
textField.resignFirstResponder()
return true
}
}
And this is MyTableViewCell.swift:
import UIKit
class MyTableViewCell: UITableViewCell {
let medColor: UIColor = UIColor(red: 0.973, green: 0.388, blue: 0.173, alpha: 1)
init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
self.textColor = UIColor.whiteColor()
self.backgroundColor = medColor
self.selectionStyle = UITableViewCellSelectionStyle.None
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I am using iOS8 as deployment target (not sure of the difference it will make).
Add these two functions:
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Swift 3.0:
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Swift 4.2
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
You can try this:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
NamesTable.beginUpdates()
Names.removeAtIndex(indexPath.row)
NamesTable.deleteRowsAtIndexPaths([indexPath], withRowAnimation: nil)
NamesTable.endUpdates()
}
}
If you're supporting iOS11+ please see the discussion:
Use the performBatchUpdates(_:completion:) method instead of this one whenever possible.
Another way that allows you to change the text of "Delete" and add more buttons when sliding a cell is to use editActionsForRowAtIndexPath.
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: (UITableView!), commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: (NSIndexPath!)) {
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var deleteAction = UITableViewRowAction(style: .Default, title: "Delete") {action in
//handle delete
}
var editAction = UITableViewRowAction(style: .Normal, title: "Edit") {action in
//handle edit
}
return [deleteAction, editAction]
}
canEditRowAtIndexPath and commitEditingStyle are still required, but you can leave commitEditingStyle empty since deletion is handled in editActionsForRowAtIndexPath.
It's new feature in iOS11 and Swift 4.
Reference link :
Trailing Swipe :
#available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .destructive, title: "Delete") { (action, sourceView, completionHandler) in
print("index path of delete: \(indexPath)")
completionHandler(true)
}
let rename = UIContextualAction(style: .normal, title: "Edit") { (action, sourceView, completionHandler) in
print("index path of edit: \(indexPath)")
completionHandler(true)
}
let swipeActionConfig = UISwipeActionsConfiguration(actions: [rename, delete])
swipeActionConfig.performsFirstActionWithFullSwipe = false
return swipeActionConfig
}
import UIKit
class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource
{
var items: String[] = ["We", "Heart", "Swift","omnamay shivay","om namay bhagwate vasudeva nama"]
var cell : UITableViewCell
}
#IBOutlet var tableview:UITableView
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if !cell {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")}
cell!.textLabel.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
return true
}
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
if let tv=tableView
{
items.removeAtIndex(indexPath!.row)
tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
}
}
use it :
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
langData.removeAtIndex(indexPath.row) //langData is array from i delete values
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
hope it helps you
I used tableViewCell to show multiple data, after swipe () right to left on a cell it will show two buttons Approve And reject, there are two methods, the first one is ApproveFunc which takes one argument, and the another one is RejectFunc which also takes one argument.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let Approve = UITableViewRowAction(style: .normal, title: "Approve") { action, index in
self.ApproveFunc(indexPath: indexPath)
}
Approve.backgroundColor = .green
let Reject = UITableViewRowAction(style: .normal, title: "Reject") { action, index in
self.rejectFunc(indexPath: indexPath)
}
Reject.backgroundColor = .red
return [Reject, Approve]
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func ApproveFunc(indexPath: IndexPath) {
print(indexPath.row)
}
func rejectFunc(indexPath: IndexPath) {
print(indexPath.row)
}
Swift 4 -- #available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let edit = UIContextualAction(style: .normal, title: "") { (action, view, nil) in
let refreshAlert = UIAlertController(title: "Deletion", message: "Are you sure you want to remove this item from cart? ", preferredStyle: .alert)
refreshAlert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action: UIAlertAction!) in
}))
refreshAlert.addAction(UIAlertAction(title: "No", style: .default, handler: { (action: UIAlertAction!) in
refreshAlert .dismiss(animated: true, completion: nil)
}))
self.present(refreshAlert, animated: true, completion: nil)
}
edit.backgroundColor = #colorLiteral(red: 0.3215686275, green: 0.5960784314, blue: 0.2470588235, alpha: 1)
edit.image = #imageLiteral(resourceName: "storyDelete")
let config = UISwipeActionsConfiguration(actions: [edit])
config.performsFirstActionWithFullSwipe = false
return config
}
As of Xcode 6.1.1, there are some tiny changes to Dash's answer.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Swift 3:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// delete data and row
dataList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
Swift 3 with custom title supported
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
//If you want to change title
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Cancel"
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// you might want to delete the item at the array first before calling this function
tableView.deleteRows(at: indexPath, with: .automatic)
}
}
Works for me in Swift 2.0
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
override func tableView(tableView: UITableView,
editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let block = UITableViewRowAction(style: .Normal, title: "Block") { action, index in
print("Block")
self.removeObjectAtIndexPath(indexPath, animated: true)
}
let delete = UITableViewRowAction(style: .Default, title: "Delete") { action, index in
print("Delete")
self.removeObjectAtIndexPath(indexPath, animated: true)
}
return [delete, block]
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "DELETE"){(UITableViewRowAction,NSIndexPath) -> Void in
print("What u want while Pressed delete")
}
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "EDIT"){(UITableViewRowAction,NSIndexPath) -> Void in
print("What u want while Pressed Edit")
}
edit.backgroundColor = UIColor.blackColor()
return [delete,edit]
}
In Swift 4 tableview add, swipe to delete UITableViewCell
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
// delete item at indexPath
}
return [delete]
}
Swift 5
Since UITableViewRowAction was deprecated in iOS 13.0 so you can use UISwipeActionsConfiguration
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { (contextualAction, view, boolValue) in
self.deleteData(at: indexPath)
}
let editAction = UIContextualAction(style: .normal, title: "Edit") { (contextualAction, view, boolValue) in
self.editData(at: indexPath)
}
editAction.backgroundColor = .purple
let swipeActions = UISwipeActionsConfiguration(actions: [deleteAction,editAction])
return swipeActions
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func deleteData(at indexPath: IndexPath) {
print(indexPath.row)
}
func editData(at indexPath: IndexPath) {
print(indexPath.row)
}
Swift 4
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "", handler: { (action,view,completionHandler ) in
//do stuff
completionHandler(true)
let data:NSDictionary = self.conversations[indexPath.row] as! NSDictionary
print(data)
let alert:UIAlertController = UIAlertController(title: "", message: "are you sure want to delete ?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel, handler: { (action) in
}))
self.present(alert, animated: true, completion: nil)
})
action.image = UIImage(named: "")
action.backgroundColor = UIColor(red: 0/255, green: 148/255, blue: 204/255, alpha: 1.0)
let confrigation = UISwipeActionsConfiguration(actions: [action])
return confrigation
}
Simply add method:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: UITableViewRowActionStyle.destructive, title: "Delete") { (action, indexPath) in
self.arrayFruit.remove(at: indexPath.row)
self.tblList.reloadData()
}
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Edit") { (action, indexpath) in
let alert = UIAlertController(title: "FruitApp", message: "Enter Fuit Name", preferredStyle: UIAlertControllerStyle.alert)
alert.addTextField(configurationHandler: { (textField) in
textField.placeholder = "Enter new fruit name"
})
alert.addAction(UIAlertAction(title: "Update", style: UIAlertActionStyle.default, handler: { [weak alert](_) in
let textField = alert?.textFields![0]
self.arrayFruit[indexPath.row] = (textField?.text!)!
self.tblList.reloadData()
}))
self.present(alert, animated: true, completion: nil)
}
edit.backgroundColor = UIColor.blue
return [delete,edit]
}
For > ios 13
https://gist.github.com/andreconghau/de574bdbb468e001c404a7270017bef5#file-swipe_to_action_ios13-swift
/*
SWIPE to Action
*/
func tableView(_ tableView: UITableView,
editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
// Right Swipe
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal,
title: "Favourite") { [weak self] (action, view, completionHandler) in
self?.handleMarkAsFavourite()
completionHandler(true)
}
action.backgroundColor = .systemBlue
return UISwipeActionsConfiguration(actions: [action])
}
func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
// Archive action
let archive = UIContextualAction(style: .normal,
title: "Archive") { [weak self] (action, view, completionHandler) in
self?.handleMoveToArchive()
completionHandler(true)
}
archive.backgroundColor = .systemGreen
// Trash action
let trash = UIContextualAction(style: .destructive,
title: "Trash") { [weak self] (action, view, completionHandler) in
self?.handleMoveToTrash(book: (self?.books![indexPath.row]) as! BookItem)
completionHandler(true)
}
trash.backgroundColor = .systemRed
// Unread action
let unread = UIContextualAction(style: .normal,
title: "Mark as Unread") { [weak self] (action, view, completionHandler) in
self?.handleMarkAsUnread()
completionHandler(true)
}
unread.backgroundColor = .systemOrange
let configuration = UISwipeActionsConfiguration(actions: [trash, archive, unread])
// If you do not want an action to run with a full swipe
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
private func handleMarkAsFavourite() {
print("Marked as favourite")
}
private func handleMarkAsUnread() {
print("Marked as unread")
}
private func handleMoveToTrash(book: BookItem) {
print("Moved to trash")
print(book)
let alert = UIAlertController(title: "Hi!", message: "Bạn có muốn xóa \(book.name)", preferredStyle: .alert)
let ok = UIAlertAction(title: "Xóa", style: .default, handler: { action in
book.delete()
self.listBook.reloadData()
})
alert.addAction(ok)
let cancel = UIAlertAction(title: "Hủy", style: .default, handler: { action in
})
alert.addAction(cancel)
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})
}
private func handleMoveToArchive() {
print("Moved to archive")
}
SWIFT 3 -- UIViewController
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
print("delete tableview cell")
}
}
swift 3
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
arrayCityName.remove(at: indexPath.row)
self.tableCityName.reloadData()
}
}
just add these
assuming your data array is 'data'
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
if let tv=table
{
data.remove(at: indexPath.row)
tv.deleteRows(at: [indexPath], with: .fade)
}
}
}
func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? {
let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
//handle like delete button
print("share button tapped")
}
share.backgroundColor = .lightGray
let delete = UITableViewRowAction(style: .normal, title: "Delete") { action, index in
self.nameArray.remove(at: editActionsForRowAt.row)
self.swipeTable.beginUpdates()
self.swipeTable.deleteRows(at: [editActionsForRowAt], with: .right)
self.swipeTable.endUpdates()
print("delete button tapped")
}
delete.backgroundColor = .orange
return [share,delete]
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let editAction = UIContextualAction.init(style: UIContextualAction.Style.normal, title: "Edit", handler: { (action, view, completion) in
//TODO: Edit
completion(true)
self.popUpViewPresent(index:indexPath.row)
})
let deleteAction = UIContextualAction.init(style: UIContextualAction.Style.destructive, title: "Delete", handler: { (action, view, completion) in
//TODO: Delete
completion(true)
self.deleteTagAction(senderTag:indexPath.row)
})
editAction.image = UIImage(named: "Edit-white")
deleteAction.image = UIImage(named: "Delete-white")
editAction.backgroundColor = UIColor.gray
deleteAction.backgroundColor = UIColor.red
let config = UISwipeActionsConfiguration(actions: [deleteAction, editAction])
config.performsFirstActionWithFullSwipe = false
return config
}
Xcode asks for UIContextualAction, here what worked for me for the updated version:
For Trailing Swipe Actions:->
func delete(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
let company = companies[indexPath.row]
let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, _) in
// Perform Delete Action
}
return action
}
func edit(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
let action = UIContextualAction(style: .normal, title: "Edit") { (action, view, escaping) in
// Perform Edit Action
}
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
}
For Leading Swipe Actions:->
func delete(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
let company = companies[indexPath.row]
let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, _) in
// Perform Delete Action
}
return action
}
func edit(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
let action = UIContextualAction(style: .normal, title: "Edit") { (action, view, escaping) in
// Perform Edit Action
}
return action
}
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = self.delete(forRowAtIndexPath: indexPath)
let edit = self.edit(forRowAtIndexPath: indexPath)
let swipe = UISwipeActionsConfiguration(actions: [delete, edit])
return swipe
}
Return true for canEditRowAt for tableView Delegate:->
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

Resources