Question UITableViewCell, affichez le bouton Supprimer sur le balayage


Comment puis-je obtenir le bouton de suppression à afficher lors de la lecture d'un UITableViewCell? L'événement n'est jamais déclenché et le bouton Supprimer n'apparaît jamais.


533
2017-07-22 13:46


origine


Réponses:


Au démarrage dans (-viewDidLoad or in storyboard) faire:

self.tableView.allowsMultipleSelectionDuringEditing = NO;

Remplacer pour prendre en charge l'édition conditionnelle de la vue tabulaire. Cela doit seulement être mis en œuvre si vous allez revenir NO pour certains articles. Par défaut, tous les éléments sont modifiables.

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //add code here for when you hit delete
    }    
}

997
2017-07-22 14:09



Cette réponse a été mise à jour pour Swift 3

Je pense toujours qu'il est agréable d'avoir un exemple très simple et autonome, de sorte que rien n'est supposé quand j'apprends une nouvelle tâche. Cette réponse est celle pour la suppression UITableView lignes Le projet fonctionne comme ceci:

enter image description here

Ce projet est basé sur le Exemple UITableView pour Swift.

Ajouter le code

Créez un nouveau projet et remplacez le code ViewController.swift par ce qui suit.

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // These strings will be the data for the table view cells
    var animals: [String] = ["Horse", "Cow", "Camel", "Pig", "Sheep", "Goat"]

    let cellReuseIdentifier = "cell"

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // It is possible to do the following three things in the Interface Builder
        // rather than in code if you prefer.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }

    // number of rows in table view
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.animals.count
    }

    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!

        cell.textLabel?.text = self.animals[indexPath.row]

        return cell
    }

    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You tapped cell number \(indexPath.row).")
    }

    // 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
            animals.remove(at: indexPath.row)

            // delete the table view row
            tableView.deleteRows(at: [indexPath], with: .fade)

        } else if editingStyle == .insert {
            // Not used in our example, but if you were adding a new row, this is where you would do it.
        }
    }

}

La méthode de clé unique dans le code ci-dessus qui permet la suppression de ligne est le dernier. Ici encore c'est pour l'emphase:

// 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
        animals.remove(at: indexPath.row)

        // delete the table view row
        tableView.deleteRows(at: [indexPath], with: .fade)

    } else if editingStyle == .insert {
        // Not used in our example, but if you were adding a new row, this is where you would do it.
    }
}

Storyboard

Ajouter un UITableView au contrôleur de vue dans le storyboard. Utilisez la mise en page automatique pour épingler les quatre côtés de la vue de la table aux bords du View Controller. Contrôlez le glisser depuis la vue de table dans le storyboard jusqu'au @IBOutlet var tableView: UITableView! ligne dans le code.

Fini

C'est tout. Vous devriez être en mesure d'exécuter votre application maintenant et de supprimer des lignes en balayant vers la gauche et en tapant "Supprimer".


Variations

Modifier le texte du bouton "Supprimer"

enter image description here

Ajoutez la méthode suivante:

func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
    return "Erase"
}

Actions de bouton personnalisé

enter image description here

Ajoutez la méthode suivante.

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    // action one
    let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
        print("Edit tapped")
    })
    editAction.backgroundColor = UIColor.blue

    // action two
    let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
        print("Delete tapped")
    })
    deleteAction.backgroundColor = UIColor.red

    return [editAction, deleteAction]
}

Notez que ceci est seulement disponible à partir d'iOS 8. Voir cette réponse pour plus de détails.

Mis à jour pour iOS 11

Les actions peuvent être placées en tête ou à la fin de la cellule en utilisant des méthodes ajoutées à l'API UITableViewDelegate dans iOS 11.

func tableView(_ tableView: UITableView,
                leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
 {
     let editAction = UIContextualAction(style: .normal, title:  "Edit", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
             success(true)
         })
editAction.backgroundColor = .blue

         return UISwipeActionsConfiguration(actions: [editAction])
 }

 func tableView(_ tableView: UITableView,
                trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
 {
     let deleteAction = UIContextualAction(style: .normal, title:  "Delete", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
         success(true)
     })
     deleteAction.backgroundColor = .red

     return UISwipeActionsConfiguration(actions: [deleteAction])
 }

En lire plus


81
2018-06-09 07:31



Ce code montre comment implémenter la suppression.

#pragma mark - UITableViewDataSource

// Swipe to delete.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_chats removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

En option, dans le remplacement de votre initialisation, ajoutez la ligne ci-dessous pour afficher l'élément du bouton Modifier:

self.navigationItem.leftBarButtonItem = self.editButtonItem;

67
2017-11-10 00:58



Note: Je n'ai pas assez de réputation pour poster un commentaire dans la réponse de Kurbz.

La réponse de Kurbz est juste. Mais pour moi ça n'a jamais marché.

Après une enquête, j'ai réalisé que glisser-supprimer se produit lorsque vous ne modifiez PAS la vue de la table..

Je n'ai jamais vu cela explicitement déclaré comme tel. Sauf erreur, je n'ai trouvé aucun autre moyen de le faire fonctionner.

Lorsque vous modifiez, le contrôle de suppression et / ou de réorganisation apparaît.


33
2018-01-20 14:18



J'ai eu un problème que je viens de résoudre et je le partage car cela peut aider quelqu'un.

J'ai un UITableView et ajouté les méthodes montrées pour permettre à balayage de supprimer:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //add code here for when you hit delete
    }    
}

Je travaille sur une mise à jour qui me permet de mettre la table en mode édition et active le multiselect. Pour ce faire, j'ai ajouté le code de Apple TableMultiSelect échantillon. Une fois que j'ai eu ce travail, j'ai trouvé que mon balayage de la fonction de suppression avait cessé de fonctionner.

Il s'avère que l'ajout de la ligne suivante à viewDidLoad était le problème:

self.tableView.allowsMultipleSelectionDuringEditing = YES;

Avec cette ligne, le multiselect fonctionnerait mais le glissement à supprimer ne fonctionnerait pas. Sans la ligne c'était l'inverse.

Le correctif:

Ajoutez la méthode suivante à votre viewController:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    self.tableView.allowsMultipleSelectionDuringEditing = editing; 
    [super setEditing:editing animated:animated];
}

Ensuite, dans votre méthode qui met la table en mode d'édition (à partir d'un appui sur un bouton par exemple), vous devez utiliser:

[self setEditing:YES animated:YES];

au lieu de:

[self.tableView setEditing:YES animated:YES];

Cela signifie que multiselect n'est activé que lorsque la table est en mode d'édition.


23
2017-10-25 15:19



Au-dessous de UITableViewDataSource vous aidera à faire glisser la suppression

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [arrYears removeObjectAtIndex:indexPath.row];
        [tableView reloadData];
    }
}

arrYears  est un NSMutableArray, puis recharger la tableView

Rapide

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

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyleDelete {
        arrYears.removeObjectAtIndex(indexPath.row)
        tableView.reloadData()
    }
}

16
2017-11-26 07:36



Dans iOS 8 et Swift 2.0, essayez ceci,

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
   // let the controller to know that able to edit tableView's row 
   return true
}

override func tableView(tableView: UITableView, commitEdittingStyle editingStyle UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)  {
   // if you want to apply with iOS 8 or earlier version you must add this function too. (just left in blank code)
}

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?  {
   // add the action button you want to show when swiping on tableView's cell , in this case add the delete button.
   let deleteAction = UITableViewRowAction(style: .Default, title: "Delete", handler: { (action , indexPath) -> Void in

   // Your delete code here.....
   .........
   .........
   })

   // You can set its properties like normal button
   deleteAction.backgroundColor = UIColor.redColor()

   return [deleteAction]
}

16
2017-07-08 16:06



@ La réponse de Kurbz est géniale, mais je veux laisser cette note et j'espère que cette réponse permettra aux gens de gagner du temps.

J'ai parfois eu ces lignes dans mon contrôleur, et ils ont fait la fonction de balayage ne fonctionne pas.

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewCellEditingStyleNone; 
}

Si tu utilises UITableViewCellEditingStyleInsert ou UITableViewCellEditingStyleNone en tant que style d'édition, la fonction de balayage ne fonctionne pas. Vous ne pouvez utiliser UITableViewCellEditingStyleDelete, qui est le style par défaut.


9
2018-01-06 16:10



En outre, cela peut être réalisé dans SWIFT en utilisant la méthode comme suit

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if (editingStyle == UITableViewCellEditingStyle.Delete){
        testArray.removeAtIndex(indexPath.row)
        goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}

7
2018-02-06 09:54



Swift 3

Tout ce que vous avez à faire est d'activer ces deux fonctions:

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

    return true

}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == UITableViewCellEditingStyle.delete {
        tableView.reloadData()
    }

}

7
2017-12-19 16:34



Swift 4

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
        // delete item at indexPath
    tableView.deleteRows(at: [indexPath], with: .fade)

    }
    return [delete]
}

6
2017-10-25 10:45