Come faccio a visualizzare il pulsante Elimina quando scorro su un UITableViewCell
? L'evento non viene mai generato e il pulsante Elimina non viene mai visualizzato.
UITableViewCell
s.
Come faccio a visualizzare il pulsante Elimina quando scorro su un UITableViewCell
? L'evento non viene mai generato e il pulsante Elimina non viene mai visualizzato.
UITableViewCell
s.
Risposte:
Durante l'avvio in (-viewDidLoad or in storyboard)
do:
self.tableView.allowsMultipleSelectionDuringEditing = NO;
Sostituisci per supportare la modifica condizionale della vista tabella. Questo deve essere implementato solo se tornerai NO
per alcuni articoli. Per impostazione predefinita, tutti gli elementi sono modificabili.
- (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
}
}
self.tableView.allowsMultipleSelectionDuringEditing = NO;
il funzionamento con il tocco sinistro. Mi sembra un bug perché la tabella NON è in stato di modifica. Questa opzione dovrebbe applicare solo "Durante l'editing". Tuttavia, ora funziona e l'ho impostato su SÌ ogni volta che la tabella entra nello stato di modifica.
Questa risposta è stata aggiornata a Swift 3
Penso sempre che sia bello avere un esempio molto semplice e autonomo in modo che nulla venga assunto quando sto imparando un nuovo compito. Questa risposta è quella per eliminare le UITableView
righe. Il progetto si comporta così:
Questo progetto si basa sull'esempio di UITableView per Swift .
Creare un nuovo progetto e sostituire il codice ViewController.swift con il seguente.
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.
}
}
}
Il metodo a chiave singola nel codice sopra che consente l'eliminazione della riga è l'ultimo. Eccolo di nuovo per enfasi:
// 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.
}
}
Aggiungi UITableView
a al View Controller nello storyboard. Utilizzare il layout automatico per bloccare i quattro lati della vista tabella ai bordi del View Controller. Controlla il trascinamento dalla vista tabella nello storyboard alla @IBOutlet var tableView: UITableView!
riga nel codice.
È tutto. Dovresti essere in grado di eseguire l'app ora ed eliminare le righe scorrendo verso sinistra e toccando "Elimina".
Modifica il testo del pulsante "Elimina"
Aggiungi il seguente metodo:
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Erase"
}
Azioni con pulsanti personalizzati
Aggiungi il seguente metodo
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]
}
Nota che questo è disponibile solo da iOS 8. Vedi questa risposta per maggiori dettagli.
Aggiornato per iOS 11
Le azioni possono essere posizionate all'inizio o alla fine della cella usando i metodi aggiunti all'API UITableViewDelegate in 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])
}
UITableView
una , questo è un progetto da solo completamente stare in piedi e non c'è bisogno di fare nulla che non sia qui descritto. Il motivo per cui ho iniziato a impostarlo nel codice è che richiede meno spiegazioni nelle mie risposte. Dovrei tornare indietro e modificare l'esempio di base per usare anche il codice.
Questo codice mostra come implementare l'eliminazione.
#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];
}
}
Facoltativamente, nella sostituzione di inizializzazione, aggiungi la riga seguente per mostrare l'elemento del pulsante Modifica:
self.navigationItem.leftBarButtonItem = self.editButtonItem;
Ho avuto un problema che sono appena riuscito a risolvere, quindi lo condivido perché potrebbe aiutare qualcuno.
Ho un UITableView e ho aggiunto i metodi mostrati per abilitare lo scorrimento per eliminare:
- (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
}
}
Sto lavorando a un aggiornamento che mi consente di mettere la tabella in modalità di modifica e abilita la selezione multipla. Per fare ciò ho aggiunto il codice dell'esempio TableMultiSelect di Apple . Una volta che ho funzionato ho scoperto che il mio colpo la funzione di eliminazione aveva smesso di funzionare.
Si è scoperto che il problema era l'aggiunta della seguente riga a viewDidLoad:
self.tableView.allowsMultipleSelectionDuringEditing = YES;
Con questa riga in, la selezione multipla funzionerebbe ma il colpo da eliminare non funzionerebbe. Senza la linea era il contrario.
La correzione:
Aggiungi il seguente metodo al tuo viewController:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
self.tableView.allowsMultipleSelectionDuringEditing = editing;
[super setEditing:editing animated:animated];
}
Quindi nel tuo metodo che mette la tabella in modalità di modifica (ad esempio premendo un pulsante) dovresti usare:
[self setEditing:YES animated:YES];
invece di:
[self.tableView setEditing:YES animated:YES];
Ciò significa che la selezione multipla è abilitata solo quando la tabella è in modalità di modifica.
Sotto UITableViewDataSource ti aiuterà a eliminare il colpo
- (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 è un NSMutableArray e quindi ricarica tableView
veloce
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()
}
}
In iOS 8 e Swift 2.0, prova questo,
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 risposta di Kurbz è fantastica, ma voglio lasciare questa nota e spero che questa risposta possa far risparmiare un po 'di tempo alle persone.
Occasionalmente avevo queste linee nel mio controller e rendevano la funzione di scorrimento non funzionante.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
Se usi UITableViewCellEditingStyleInsert
o UITableViewCellEditingStyleNone
come stile di modifica, la funzione di scorrimento non funziona. Puoi usare solo UITableViewCellEditingStyleDelete
, che è lo stile predefinito.
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]
}
Inoltre, ciò può essere ottenuto in SWIFT usando il metodo come segue
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
testArray.removeAtIndex(indexPath.row)
goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
Tutto quello che devi fare è abilitare queste due funzioni:
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()
}
}
So che è una vecchia domanda, ma la risposta di @Kurbz ne ha bisogno solo per Xcode 6.3.2 e SDK 8.3
Ho bisogno di aggiungere [tableView beginUpdates]
e [tableView endUpdates]
(grazie a @ bay.phillips qui )
// 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];
}
Quando rimuovi una cella della vista tabella, devi anche rimuovere l'oggetto array nell'indice x.
Penso che puoi rimuoverlo usando un gesto di scorrimento. La vista tabella chiamerà il delegato:
- (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];
}
}
Dopo aver rimosso l'oggetto. Devi ricaricare l'uso di tableview. Aggiungi la seguente riga nel tuo codice:
[tableView reloadData];
successivamente, la riga è stata eliminata correttamente. E quando ricarichi la vista o aggiungi dati a DataSource l'oggetto non sarà più lì.
Per tutti gli altri è corretta la risposta di Kurbz.
Volevo solo ricordarti che la funzione di delegato non sarà sufficiente se desideri rimuovere l'oggetto dall'array DataSource.
Spero di averti aiutato.
[tableView reloadData]
chiama [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]
.
- (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];
}
}
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]
}
Per Swift, basta scrivere questo codice
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
print("Delete Hit")
}
}
Per l'obiettivo C, basta scrivere questo codice
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(@"index: %@",indexPath.row);
}
}
per il codice swift4, prima abilita la modifica:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
quindi aggiungi l'azione di eliminazione al delegato di modifica:
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]
}
Swift 4,5
Per eliminare una cella al passaggio del dito ci sono due metodi integrati di UITableView. Scrivere questo metodo nell'estensione dataView di TableView.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = deleteProperty(at: indexPath)
return UISwipeActionsConfiguration(actions: [delete])
}
//Declare this method in Viewcontroller Main and modify according to your need
func deleteProperty(at indexpath: IndexPath) -> UIContextualAction {
let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completon) in
self.yourArray.remove(at: indexpath) //Removing from array at selected index
completon(true)
action.backgroundColor = .red //cell background color
}
return action
}
Se stai adottando fonti di dati diffuse, dovrai spostare i callback delegati in una UITableViewDiffableDataSource
sottoclasse. Per esempio:
class DataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let identifierToDelete = itemIdentifier(for: indexPath) {
var snapshot = self.snapshot()
snapshot.deleteItems([identifierToDelete])
apply(snapshot)
}
}
}
}