Pregunta UITableViewCell, muestra el botón Eliminar al deslizar


¿Cómo puedo obtener el botón Eliminar para mostrar al deslizar en un UITableViewCell? El evento nunca se levanta y el botón Eliminar nunca aparece.


533
2017-07-22 13:46


origen


Respuestas:


Durante el inicio en (-viewDidLoad or in storyboard) hacer:

self.tableView.allowsMultipleSelectionDuringEditing = NO;

Anular para admitir la edición condicional de la vista de tabla. Esto solo necesita ser implementado si vas a regresar NO para algunos artículos. Por defecto, todos los elementos son editables.

- (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



Esta respuesta se ha actualizado a Swift 3

Siempre pienso que es bueno tener un ejemplo muy simple y autónomo para que no se asuma nada cuando estoy aprendiendo una nueva tarea. Esta respuesta es para borrar UITableView filas El proyecto funciona de esta manera:

enter image description here

Este proyecto se basa en Ejemplo UITableView para Swift.

Agrega el código

Cree un nuevo proyecto y reemplace el código ViewController.swift con lo siguiente.

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

}

El método de clave única en el código anterior que habilita la eliminación de filas es el último. Aquí está de nuevo para enfatizar:

// 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

Agrega un UITableView al Controlador de Vista en el guión gráfico. Utilice el diseño automático para fijar los cuatro lados de la vista de tabla a los bordes del controlador de vista. Controle la resistencia desde la vista de tabla en el guión gráfico al @IBOutlet var tableView: UITableView! línea en el código.

Terminado

Eso es todo. Debería poder ejecutar su aplicación ahora y eliminar filas deslizando hacia la izquierda y tocando "Eliminar".


Variaciones

Cambiar el texto del botón "Eliminar"

enter image description here

Agregue el siguiente método:

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

Acciones de botones personalizados

enter image description here

Agregue el siguiente método.

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

Tenga en cuenta que esto solo está disponible en iOS 8. Ver esta respuesta para más detalles.

Actualizado para iOS 11

Las acciones se pueden ubicar ya sea al principio o al final de la celda mediante los métodos agregados a la API UITableViewDelegate en 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])
 }

Otras lecturas


81
2018-06-09 07:31



Este código muestra cómo implementar la eliminación.

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

Opcionalmente, en la anulación de inicialización, agregue la línea siguiente para mostrar el elemento del botón Editar:

self.navigationItem.leftBarButtonItem = self.editButtonItem;

67
2017-11-10 00:58



Nota: No tengo suficiente reputación para publicar un comentario en la respuesta de Kurbz.

La respuesta de Kurbz es correcta. Pero para mí nunca funcionó.

Después de algunas investigaciones, me di cuenta de que deslizar para borrar sucede cuando NO se edita la vista de tabla..

Nunca he visto esto explícitamente declarado como tal. A menos que me equivoque, no he encontrado otra forma de hacerlo funcionar.

Cuando esté editando, se mostrará el control de eliminar y / o reordenar.


33
2018-01-20 14:18



Tuve un problema que acabo de resolver, así que lo estoy compartiendo, ya que puede ayudar a alguien.

Tengo una UITableView y agregué los métodos que se muestran para habilitar el deslizamiento para eliminar:

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

Estoy trabajando en una actualización que me permite poner la tabla en modo de edición y habilita el multiselección. Para hacer eso agregué el código de Apple TableMultiSelect muestra. Una vez que obtuve ese funcionamiento, descubrí que mi deslizamiento de la función de eliminación había dejado de funcionar.

Resulta que agregar la siguiente línea a viewDidLoad era el problema:

self.tableView.allowsMultipleSelectionDuringEditing = YES;

Con esta línea, el multiselección funcionaría pero el deslizamiento para eliminar no lo haría. Sin la línea, era al revés.

La solución:

Agregue el siguiente método a su viewController:

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

Luego, en su método que pone la tabla en modo de edición (desde un botón presione, por ejemplo) debe usar:

[self setEditing:YES animated:YES];

en lugar de:

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

Esto significa que multiselect solo está habilitado cuando la tabla está en modo de edición.


23
2017-10-25 15:19



Debajo de UITableViewDataSource te ayudará a deslizar borrar

- (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  es un NSMutableArray y luego volver a cargar el tableView

Rápido

 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



En iOS 8 y Swift 2.0, prueba esto,

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 respuesta de @Kurbz es increíble, pero quiero dejar esta nota y espero que esta respuesta pueda salvar a la gente en algún momento.

Ocasionalmente tenía estas líneas en mi controlador, y hacían que la función de deslizar no funcionara.

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

Si utiliza UITableViewCellEditingStyleInsert o UITableViewCellEditingStyleNone como el estilo de edición, la función de deslizar no funciona. Solo puedes usar UITableViewCellEditingStyleDelete, que es el estilo predeterminado.


9
2018-01-06 16:10



Además, esto se puede lograr en SWIFT usando el método de la siguiente manera

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

Todo lo que tienes que hacer es habilitar estas dos funciones:

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