Comment puis-je afficher le bouton de suppression lors du glissement sur un UITableViewCell
? L'événement n'est jamais déclenché et le bouton Supprimer n'apparaît jamais.
Pendant le démarrage dans (-viewDidLoad or in storyboard)
faire:
self.tableView.allowsMultipleSelectionDuringEditing = NO;
Remplacer pour prendre en charge l’édition conditionnelle de la vue tabulaire. Ceci ne doit être implémenté que si vous retournez NO
pour certains éléments. 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
}
}
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 afin que rien ne soit supposé lorsque j'apprends une nouvelle tâche. Cette réponse est celle pour supprimer UITableView
lignes. Le projet fonctionne comme ceci:
Ce projet est basé sur le exemple UITableView pour Swift .
Créez un nouveau projet et remplacez le code ViewController.Swift par le suivant.
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 la dernière. La voici à nouveau pour souligner:
// 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.
}
}
Ajoutez un UITableView
au contrôleur de vue dans le storyboard. Utilisez la disposition automatique pour épingler les quatre côtés de la vue de table aux bords du contrôleur de vue. Faites glisser le contrôle depuis la vue de table du storyboard vers la ligne @IBOutlet var tableView: UITableView!
du code.
C'est tout. Vous devriez pouvoir exécuter votre application maintenant et supprimer des lignes en faisant glisser votre doigt vers la gauche et en appuyant sur "Supprimer".
Modifiez le texte du bouton "Supprimer"
Ajoutez la méthode suivante:
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Erase"
}
Actions des boutons personnalisés
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 cela n’est disponible que sur 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 en queue de la cellule à l'aide de 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])
}
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];
}
}
Eventuellement, dans votre remplacement d'initialisation, ajoutez la ligne ci-dessous pour afficher l'élément de bouton Modifier:
self.navigationItem.leftBarButtonItem = self.editButtonItem;
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 cela n'a jamais fonctionné.
Après quelques recherches, je me suis rendu compte que n balayage pour supprimer se produit lorsque vous ne modifiez PAS la vue tabulaire..
Je n'ai jamais vu cela explicitement déclaré comme tel. Sauf erreur, je n'ai pas trouvé d'autre moyen de le faire fonctionner.
Lorsque vous modifiez, le contrôle de suppression et/ou de réorganisation apparaît.
J'ai eu un problème que je viens juste de résoudre, alors je le partage car cela peut aider quelqu'un.
J'ai un UITableView et ajouté les méthodes montrées pour permettre à glisser pour 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 le tableau en mode édition et active multiselect. Pour ce faire, j'ai ajouté le code de l'exemple TableMultiSelect d'Apple. Une fois que j'ai eu ce travail, j'ai constaté que mon balayage 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 multisélection fonctionnerait, mais le balayage à 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’une pression 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 la sélection multiple n'est activée que lorsque la table est en mode édition.
Ci-dessous UITableViewDataSource vous aidera à supprimer par glissement
- (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 rechargez 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()
}
}
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]
}
La réponse de @ Kurbz est géniale, mais je souhaite laisser cette note et 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 fonctionnalité de balayage ne fonctionne pas.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
Si vous utilisez UITableViewCellEditingStyleInsert
ou UITableViewCellEditingStyleNone
comme style d'édition, la fonction de balayage ne fonctionne pas. Vous ne pouvez utiliser que UITableViewCellEditingStyleDelete
, qui est le style par défaut.
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()
}
}
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]
}
En outre, ceci peut être réalisé dans Swift en utilisant la méthode suivante
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
testArray.removeAtIndex(indexPath.row)
goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
Je sais que c'est une vieille question, mais la réponse de @Kurbz en a simplement besoin pour Xcode 6.3.2 et SDK 8.3
J'ai besoin d'ajouter [tableView beginUpdates]
et [tableView endUpdates]
(merci à @ bay.phillips ici )
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// Open "Transaction"
[tableView beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// your code goes here
//add code here for when you hit delete
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
// Close "Transaction"
[tableView endUpdates];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//add code here for when you hit delete
[dataSourceArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Lorsque vous supprimez une cellule de votre table, vous devez également supprimer votre objet tableau à l'index x.
Je pense que vous pouvez l'enlever en effectuant un geste de balayage. La vue tableau appellera le délégué:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
[dataSourceArray removeObjectAtIndex:indexPath.row];
}
}
Après avoir retiré l'objet. Vous devez recharger l'utilisation de tableview. Ajoutez la ligne suivante dans votre code:
[tableView reloadData];
après cela, vous avez supprimé la ligne avec succès. Et lorsque vous rechargez la vue ou ajoutez des données à la source de données, l'objet ne sera plus là.
Pour tous les autres, la réponse de Kurbz est correcte.
Je voulais seulement vous rappeler que la fonction de délégué ne sera pas suffisante si vous souhaitez supprimer l'objet du tableau DataSource.
J'espère vous avoir aidé.
Pour Swift, écrivez simplement ce code
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
print("Delete Hit")
}
}
Pour Objective C, écrivez simplement ce code
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(@"index: %@",indexPath.row);
}
}
Swift 2.2:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView,
editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "DELETE"){(UITableViewRowAction,NSIndexPath) -> Void in
print("Your action when user pressed delete")
}
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "EDIT"){(UITableViewRowAction,NSIndexPath) -> Void in
print("Your action when user pressed edit")
}
return [delete, block]
}
pour le code Swift4, activez d'abord l'édition:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
alors vous ajoutez une action de suppression au délégué d'édition:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .destructive, title: "Delete") { (_, index) in
// delete model object at the index
self.models[index.row]
// then delete the cell
tableView.beginUpdates()
tableView.deleteRows(at: [index], with: .automatic)
tableView.endUpdates()
}
return [action]
}