para descargar caracteristicas ios uitableview ios8 uipangesturerecognizer

descargar - Deslice completamente UITableViewCell para eliminar UITableView iOS 8



ios 8.0 para iphone 4 (4)

Me gustaría imitar la función de deslizar para eliminar de un UITableViewCell como la aplicación de correo en iOS 8. No me refiero a deslizar para revelar un botón de eliminar. Me refiero a cuando se desliza, se descartan 3 acciones, pero si sigue deslizando hacia la izquierda, se eliminará el correo electrónico.

En iOS 8, UITableView tiene un nuevo método en el que puede proporcionar los datos para mostrar cualquier número de botones:

#ifdef __IPHONE_8_0 - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewRowAction *viewStackRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Stack" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { SM_LOG_DEBUG(@"View Stack Action"); }]; viewStackRowAction.backgroundColor = [UIColor radiusBlueColor]; UITableViewRowAction *viewUserRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"User" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { SM_LOG_DEBUG(@"View User Action"); }]; viewUserRowAction.backgroundColor = [UIColor radiusLightBlueColor]; UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { SM_LOG_DEBUG(@"Delete"); }]; deleteRowAction.backgroundColor = [UIColor redColor]; return @[deleteRowAction, viewUserRowAction, viewStackRowAction]; } #endif

No veo ninguna API para detectar si sigues deslizando. He grepped para 8_0 en UITableView.h y el método anterior parece ser el único nuevo.

Supongo que uno podría monitorear el desplazamiento de la vista de desplazamiento, o agregar / secuestrar un UIPanGestureRecognizer. Solo quería asegurarme de usar la forma predeterminada, si existe una (y obtener la animación para "gratis")


Con Swift 4.2 y iOS 12, de acuerdo con sus necesidades, puede elegir una de las 3 formas siguientes para crear una acción de barrido final que eliminará el UITableViewCell seleccionado.

# 1. Usando el UITableViewDataSource de tableView(_:commit:forRowAt:)

Cuando usa tableView(_:commit:forRowAt:) con un estilo de editingStyle de valor UITableViewCell.EditingStyle.delete , el sistema admite automáticamente el deslizamiento completo para eliminar.

import UIKit class TableViewController: UITableViewController { var numbers = [Int](0..<10) override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numbers.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "/(numbers[indexPath.row])" return cell } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if (editingStyle == UITableViewCell.EditingStyle.delete) { self.numbers.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) } } }

# 2. Uso de UITableViewDelegate de tableView(_:editActionsForRowAt:) y UITableViewRowAction

Para admitir el barrido completo para eliminar con UITableViewRowAction , debe inicializarlo con un style que tenga un valor de UITableViewRowAction.Style.destructive .

import UIKit class TableViewController: UITableViewController { var numbers = [Int](0..<10) override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numbers.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "/(numbers[indexPath.row])" return cell } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { // Intentionally blank in order to be able to use UITableViewRowActions } override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { let deleteHandler: (UITableViewRowAction, IndexPath) -> Void = { _, indexPath in self.numbers.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) } let deleteAction = UITableViewRowAction(style: UITableViewRowAction.Style.destructive, title: "Delete", handler: deleteHandler) // Add more actions here if required return [deleteAction] } }

# 3. Uso de UITableViewDelegate de tableView(_:trailingSwipeActionsConfigurationForRowAt:) y UISwipeActionsConfiguration (requiere iOS 11)

UISwipeActionsConfiguration tiene una propiedad llamada performsFirstActionWithFullSwipe . performsFirstActionWithFullSwipe tiene la siguiente declaración:

var performsFirstActionWithFullSwipe: Bool { get set }

Un valor booleano que indica si un barrido completo realiza automáticamente la primera acción. [...] Cuando esta propiedad se establece en true , un barrido completo en la fila realiza la primera acción enumerada en la propiedad de actions . El valor predeterminado de esta propiedad es true .

La siguiente implementación de UITableViewController muestra cómo utilizar UISwipeActionsConfiguration para administrar el barrido completo para eliminar acciones.

import UIKit class TableViewController: UITableViewController { var numbers = [Int](0..<10) override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numbers.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "/(numbers[indexPath.row])" return cell } override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let handler: UIContextualAction.Handler = { (action: UIContextualAction, view: UIView, completionHandler: ((Bool) -> Void)) in self.numbers.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) completionHandler(true) } let deleteAction = UIContextualAction(style: UIContextualAction.Style.destructive, title: "Delete", handler: handler) // Add more actions here if required let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) configuration.performsFirstActionWithFullSwipe = true return configuration } }


El origen de datos de la vista de tabla tiene que implementar

-tableView:commitEditingStyle:forRowAtIndexPath:

de lo contrario, la funcionalidad de deslizamiento de iOS 8 incorporada no funcionará.

Esto parece contrario a la UITableViewRowAction ya que un UITableViewRowAction acepta un bloque. Pero es la única forma en que he podido hacerlo funcionar.


Puede utilizar MGSwipeTableCell . Han implementado esta función para activar la devolución de llamada swipeTableCell: tappedButtonAtIndex: direction: fromExpansion: con tappedButtonAtIndex igual a 0 (para que se ejecute lo que implementó en el primer botón agregado).


agregue el reconocedor ui gustere a cada celda, verifique la cantidad de "swipness", si se encuentra por encima de un umbral específico, haga la eliminación.

algo como:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"identifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]]; } UISwipeGestureRecognizer* swipe_gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)]; [swipe_gesture setDirection:UISwipeGestureRecognizerDirectionLeft]; [cell addGestureRecognizer:swipe_gesture]; return cell; } - (void)swipeLeft:(UIGestureRecognizer *)gestureRecognizer { int threshold = 100; if (sender.state == UIGestureRecognizerStateBegan) { startLocation = [sender locationInView:self.view]; } else if (sender.state == UIGestureRecognizerStateEnded) { CGPoint stopLocation = [sender locationInView:self.view]; CGFloat dx = stopLocation.x - startLocation.x; CGFloat dy = stopLocation.y - startLocation.y; CGFloat distance = sqrt(dx*dx + dy*dy ); if (distance > threshold ) { NSLog(@"DELETE_ROW"); } } }