web-dev-qa-db-fra.com

Comment permettre à swipe de supprimer une cellule dans un tableau?

J'ai un UIViewController qui implémente le délégué et la source de données de TableViews protocoles. Maintenant, je veux ajouter un geste "glisser pour supprimer" aux cellules.

Comment devrais-je m'y prendre?.

J'ai donné une implémentation vierge de la méthode commitEditingStyle et également défini la propriété Editing sur YES.

La fonctionnalité de balayage ne vient toujours pas.

Maintenant, dois-je ajouter séparément UISwipeGesture à chaque cellule?

Ou est-ce que je manque quelque chose?

74
Amogh Talpallikar

Vous n'êtes pas obligé de définir editing:YES si vous devez afficher le bouton Supprimer lors du balayage de cellule. Vous devez implémenter tableView:canEditRowAtIndexPath: et retournez YES pour les lignes que vous devez éditer/supprimer. Cela n'est pas nécessaire lorsque la source de données de votre table est une sous-classe de UITableViewContoller - cette méthode, si elle n'est pas remplacée, renvoie YES par défaut. Dans tous les autres cas, vous devez l'implémenter.

EDIT: Ensemble nous avons trouvé le problème - tableView:editingStyleForRowAtIndexPath: retourné UITableViewCellEditingStyleNone si la table n'était pas en mode édition.

53
Kyr Dunenkoff

Comme Dan a commenté ci-dessus, vous devez implémenter les méthodes de délégué de la vue tableau suivantes:

  1. tableView:canEditRowAtIndexPath:
  2. tableView:commitEditingStyle:forRowAtIndexPath:

Remarque: j'ai essayé ceci sous iOS 6 et iOS 7.

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return YES - we will be able to delete all rows
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Perform the real delete action here. Note: you may need to check editing style
    //   if you do not perform delete only.
    NSLog(@"Deleted row.");
}
61
Dj S
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not 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) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
25
Can Aksoy

S'il vous plaît essayez ce code dans Swift,

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, commitEditingStyle 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]
}
13
Masa S-AiYa

Essayez d’ajouter ce qui suit à votre classe:

// Override to support conditional editing of the table view.
- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return(YES);
}
5
David M. Syzdek

Conclusion de Kyr Dunenkoff le chat est

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {

}

ne doit pas être défini si vous avez besoin que le bouton Supprimer apparaisse lors du balayage.

3
Thiru

Si vous utilisez un NSFetchedResultsControllerDelegate pour remplir la vue tableau, cela a fonctionné pour moi:

  • Assure-toi tableView:canEditRowAtIndexPath retourne toujours vrai
  • Dans votre tableView:commitEditingStyle:forRowAtIndexPath _ implémentation, ne supprimez pas la ligne directement à partir de la vue tableau. Au lieu de cela, supprimez-le à l'aide du contexte de votre objet géré, par exemple:

    if editingStyle == UITableViewCellEditingStyle.Delete {
        let Word = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Word
        self.managedObjectContext.deleteObject(Word)
        self.saveManagedObjectContext()
    }
    
    func saveManagedObjectContext() {
        do {
            try self.managedObjectContext.save()
        } catch {
            let saveError = error as NSError
            print("\(saveError), \(saveError.userInfo)")
        }
    }
    
1
GabeV

D'après mon expérience, il semble que vous deviez avoir editing sur UITableView défini sur NO pour que le balayage fonctionne.

self.tableView.editing = NO;

0
kgaidis

C'était un problème pour moi aussi ... Je ne pouvais que glisser pour supprimer au travail une fois toutes les 10 tentatives environ. Il se trouve que gesture sur le téléviseur était bloqué par un autre geste du contrôleur de vue parent. Le téléviseur était imbriqué dans une MMDrawerController (disposition du tiroir pouvant être balayée).

Il suffit de configurer la reconnaissance des gestes dans le contrôleur de tiroir pour qu’elle ne réponde pas aux gestes rapprochés dans les tiroirs flanquants.

Vous pouvez aussi essayer de faire quelque chose comme ça avec le gesture delegate:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
0
Kevin

Ceci est la version Swift

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the specified item to be editable.
    return true
}

// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }    
}
0
JZAU

Après iOS 8.0, vous pouvez personnaliser votre action dans

- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
0
user501836