web-dev-qa-db-fra.com

Ajouter un glisser pour supprimer UITableViewCell

Je suis en train de faire une application CheckList avec un UITableView. Je me demandais comment ajouter un balayage pour supprimer une UITableViewCell.

Voici mon 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

}

}

Et voici 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
}

}

J'utilise iOS8 comme cible de déploiement (je ne suis pas sûr de la différence que cela va faire).

116
jdnoon

Ajoutez ces deux fonctions:

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)
    }
}
264
Dash

Une autre méthode permettant de modifier le texte de "Supprimer" et d'ajouter d'autres boutons lors du déplacement d'une cellule consiste à utiliser 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 et commitEditingStyle sont toujours obligatoires, mais vous pouvez laisser commitEditingStyle vides, car la suppression est traitée dans editActionsForRowAtIndexPath.

22
keverly

Vous pouvez essayer ceci:

func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
    return true
}

func tableView(tableView: UITableView!, commitEditingStyle editingStyle:   UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
    if (editingStyle == UITableViewCellEditingStyle.Delete) {
        NamesTable.beginUpdates()
        Names.removeAtIndex(indexPath!.row)
        NamesTable.deleteRowsAtIndexPaths([indexPath], withRowAnimation: nil)
        NamesTable.endUpdates()

    }
}
20
ANIL.MUNDURU
    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)



        }
    }
}


}
14
VARUN SINGHAL

utilise le :

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)
    }
}

espérons que cela vous aide

7
Subhash Sharma

C'est une nouvelle fonctionnalité dans iOS11 et Swift 4. 

Lien de référence:

Balayage suivi:

@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
}

 enter image description here

7
Bhadresh

Swift 3 avec titre personnalisé pris en charge

        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)
                }
            }
5
Basil Mariano

Fonctionne pour moi dans 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]
}
4
Tristan.Liu

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)
    }
}
4
Hong Duan

Depuis Xcode 6.1.1, de petits changements ont été apportés à la réponse de Dash.

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)
        }
    }
4
TimWhiting

Dans Swift 4 tableview add, glissez pour supprimer 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]
}
4
Pratik Lad
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]
}
3
Piyush Sanepara

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
        }
2
Vishal Vaghasiya

J'ai utilisé tableViewCell pour afficher plusieurs données. Après avoir glissé () de droite à gauche sur une cellule, il affichera deux boutons Approuver et rejeter. Il existe deux méthodes. prend un argument.  enter image description here 

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)
}
2
akbar khan

Swift 4 - @ disponible (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
}
2
pravasi steffi

Ajoutez simplement la méthode:

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]
}

 enter image description here

1
Mr.Javed Multani
@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
    }
0
Sai kumar Reddy

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")
    }
}
0
BennyTheNerd

ajoutez simplement ces en supposant que votre tableau de données est '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)



        }
    }
}
0
Hatim

ici Voir mon résultat Swift avec bouton entièrement personnalisable supporté

Bonus d'avance pour utiliser cette seule méthode d'implémentation et vous obtenez un bouton parfait !!!

 func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let action = UIContextualAction(
            style: .destructive,
            title: "",
            handler: { (action, view, completion) in

                let alert = UIAlertController(title: "", message: "Are you sure you want to delete this incident?", preferredStyle: .actionSheet)

                alert.addAction(UIAlertAction(title: "Delete", style: .destructive , handler:{ (UIAlertAction)in
                    let model = self.incedentArry[indexPath.row] as! HFIncedentModel
                    print(model.incent_report_id)
                    self.incedentArry.remove(model)
                    tableView.deleteRows(at: [indexPath], with: .fade)
                    delete_incedentreport_data(param: ["incent_report_id": model.incent_report_id])
                    completion(true)
                }))

                alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction)in
                    tableView.reloadData()
                }))

                self.present(alert, animated: true, completion: {

                })


        })
        action.image = HFAsset.ic_trash.image
        action.backgroundColor = UIColor.red
        let configuration = UISwipeActionsConfiguration(actions: [action])
        configuration.performsFirstActionWithFullSwipe = true
        return configuration
}
0
Paresh Mangukiya

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()
    }
}
0
Deepak Tagadiya