UITableViewCell, Pokaż przycisk Usuń przy przesunięciu

Jak wyświetlić przycisk Usuń podczas przesuwania na UITableViewCell? Zdarzenie nigdy nie zostanie wywołane, a przycisk Usuń nigdy się nie pojawi.

Author: Suragch, 2010-07-22

17 answers

Podczas uruchamiania w (-viewDidLoad or in storyboard) do:

self.tableView.allowsMultipleSelectionDuringEditing = NO;

Override do obsługi warunkowej edycji widoku tabeli. To musi być zaimplementowane tylko, jeśli zamierzasz zwracać NO dla niektórych przedmiotów. Domyślnie wszystkie elementy można edytować.

- (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
    }    
}
 1002
Author: Kurbz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 11:06:23

ta odpowiedź została zaktualizowana do Swift 3

Zawsze myślę, że miło jest mieć bardzo prosty, samodzielny przykład, tak, że nic nie jest zakładane, gdy uczę się nowego zadania. Ta odpowiedź dotyczy usuwania UITableView wierszy. Projekt działa tak:

Tutaj wpisz opis obrazka

Ten projekt jest oparty na przykładzie UITableView dla Swift.

Dodaj kod

Utwórz nowy projekt i zastąp Kontroler ViewController.kod swift z następujące.

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

}

Metoda pojedynczego klucza w powyższym kodzie, która umożliwia usuwanie wierszy, jest ostatnią. Tu znowu dla podkreślenia:

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

Dodaj UITableView do kontrolera widoku w storyboardzie. Układ automatyczny pozwala przypiąć cztery strony widoku stołu do krawędzi kontrolera widoku. Sterowanie przeciąganiem z widoku tabeli w storyboardzie do linii @IBOutlet var tableView: UITableView! w kodzie.

Zakończone

To wszystko. Powinieneś być w stanie uruchomić swój aplikacja teraz i Usuń wiersze, przesuwając w lewo i dotykając "Usuń".

Wariacje

Zmień tekst przycisku "Usuń"

Tutaj wpisz opis obrazka

Dodać następującą metodę:

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

Niestandardowe działania przycisków

Tutaj wpisz opis obrazka

Dodaj następującą metodę.

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

Zauważ, że jest to dostępne tylko z iOS 8. Zobacz ta odpowiedź Aby uzyskać więcej szczegółów.

Aktualizacja dla systemu iOS 11

Akcje mogą być umieszczane na początku lub na końcu komórki za pomocą metod dodanych do interfejsu API UITableViewDelegate w systemie 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])
 }

Czytaj dalej

 83
Author: Suragch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 22:07:28

Ten kod pokazuje jak zaimplementować delete.

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

Opcjonalnie, w nadpisaniu inicjalizacji, dodaj poniższą linię, aby wyświetlić pozycję przycisku Edytuj:

self.navigationItem.leftBarButtonItem = self.editButtonItem;
 67
Author: ma11hew28,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-10 01:09:58

Uwaga: nie mam wystarczającej reputacji, aby dodać komentarz w odpowiedzi od Kurbz.

Odpowiedź od Kurbza jest słuszna. Ale dla mnie to nigdy nie zadziałało.

Po pewnym dochodzeniu, zdałem sobie sprawę, że przesunięcie w celu usunięcia ma miejsce, gdy nie edytuje widoku tabeli..

Nigdy nie widziałem tego jednoznacznie stwierdzonego jako takiego. O ile się nie mylę, nie znalazłem innego sposobu, żeby to zadziałało.

Podczas edycji pojawi się kontrolka Usuń i / lub zmień kolejność.

 33
Author: GenesisST,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-20 14:18:08

Miałem problem, który właśnie udało mi się rozwiązać, więc dzielę się nim, ponieważ może to komuś pomóc.

Mam UITableView i dodałem pokazane metody pozwalające na usunięcie:

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

Pracuję nad aktualizacją, która pozwala mi przełączyć tabelę w tryb edycji i włączyć multiselect. Aby to zrobić, dodałem kod z tabeli Apple Tabelamultiselect sample. Gdy już to działa, odkryłem, że moje przesunięcie funkcja usuwania przestała działać.

Okazuje się, że problem polegał na dodaniu następującej linii do viewDidLoad:

self.tableView.allowsMultipleSelectionDuringEditing = YES;

Z tą linią, multiselect będzie działał, ale przesunięcie, aby usunąć nie. bez linii było odwrotnie.

Fix:

Dodaj następującą metodę do kontrolera viewController:

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

Następnie w metodzie, która wprowadza tabelę w tryb edycji (na przykład po naciśnięciu przycisku) należy użyć:

[self setEditing:YES animated:YES];

Zamiast:

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

Oznacza to, że multiselect jest włączone tylko wtedy, gdy tabela jest w trybie edycji.

 23
Author: Leon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 15:27:43

Poniżej UITableViewDataSource pomoże Ci przesunąć delete

- (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 jest NSMutableArray, a następnie przeładuj tableView

Swift

 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
Author: iAnkit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-21 05:57:57

W iOS 8 i Swift 2.0 spróbuj tego,

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
Author: Masa S-AiYa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 04:47:30

@Kurbz odpowiedź jest super, ale chcę zostawić tę notkę i mam nadzieję, że ta odpowiedź zaoszczędzi ludziom trochę czasu.

Czasami miałem te linie w kontrolerze i sprawiły, że funkcja przesuwania nie działała.

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

Jeśli używasz UITableViewCellEditingStyleInsert lub UITableViewCellEditingStyleNone jako stylu edycji, funkcja przesuwania nie działa. Możesz używać tylko UITableViewCellEditingStyleDelete, który jest domyślnym stylem.

 9
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-21 10:00:47

Można to również osiągnąć w systemie SWIFT za pomocą metody w następujący sposób

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
Author: DrPatience,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 09:54:01

Swift 3

Wystarczy włączyć te dwie funkcje:

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
Author: Machado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 16:34:20

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
Author: Pratik Lad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 00:59:29

Gdy usuniesz komórkę tableview, musisz również usunąć obiekt tablicy z indeksem x.

Myślę, że można go usunąć za pomocą gestu machnięcia. Widok tabeli wywoła delegata:

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

Po usunięciu obiektu. Musisz ponownie załadować widok tableview. Dodaj następujący wiersz w kodzie:

[tableView reloadData];

Następnie wiersz został pomyślnie usunięty. A po przeładowaniu widoku lub dodaniu danych do DataSource obiekt już tam nie będzie.

Dla wszystkich innych jest odpowiedź od Kurbz poprawne.

Chciałem tylko przypomnieć, że funkcja delegata nie wystarczy, jeśli chcesz usunąć obiekt z tablicy DataSource.

Mam nadzieję, że ci pomogłem.
 5
Author: Robybyte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-05 11:11:49
- (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];
    }    
}    
 5
Author: Rahul K Rajan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-21 11:08:59

Wiem, że to stare pytanie, ale @ Kurbz odpowiedz tylko potrzebuje tego dla Xcode 6.3.2 i SDK 8.3

Muszę dodać [tableView beginUpdates] i [tableView endUpdates] (dzięki @ bay.phillips here )

// 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];
}
 5
Author: Beto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 11:18:03

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]
}
 1
Author: lcl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 14:32:26

Dla Swifta wystarczy napisać ten kod

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            print("Delete Hit")
        }
}

Dla Objective C, po prostu napisz ten kod

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
       if (editingStyle == UITableViewCellEditingStyleDelete) {           
            NSLog(@"index: %@",indexPath.row);
           }
}
 1
Author: KiranJasvanee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-26 12:27:13

Dla kodu swift4, najpierw Włącz edycję:

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

Następnie dodajesz akcję delete do delegata edycji:

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]
}
 1
Author: Abdoelrhman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 02:13:10