Jak mogę wyświetlić przycisk usuwania, gdy przesuwasz po UITableViewCell
? Zdarzenie nigdy nie jest wywoływane, a przycisk usuwania nigdy się nie pojawia.
UITableViewCell
s.
Jak mogę wyświetlić przycisk usuwania, gdy przesuwasz po UITableViewCell
? Zdarzenie nigdy nie jest wywoływane, a przycisk usuwania nigdy się nie pojawia.
UITableViewCell
s.
Odpowiedzi:
Podczas uruchamiania w (-viewDidLoad or in storyboard)
do:
self.tableView.allowsMultipleSelectionDuringEditing = NO;
Zastąp w celu obsługi warunkowej edycji widoku tabeli. Należy to zaimplementować tylko, jeśli zamierzasz wrócić NO
po niektóre przedmioty. 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
}
}
self.tableView.allowsMultipleSelectionDuringEditing = NO;
aby lewy ruch machnięcia zadziałał. Dla mnie to brzmi jak błąd, ponieważ tabela NIE jest w stanie edycji. Ta opcja powinna mieć zastosowanie tylko „Podczas edycji”. Jednak teraz działa i ustawiam go na TAK, gdy tabela przechodzi w stan edycji.
Ta odpowiedź została zaktualizowana do wersji Swift 3
Zawsze myślę, że miło jest mieć bardzo prosty, samodzielny przykład, aby nie zakładać niczego, gdy uczę się nowego zadania. Ta odpowiedź dotyczy usuwania UITableView
wierszy. Projekt działa w następujący sposób:
Ten projekt jest oparty na przykładzie UITableView dla Swift .
Utwórz nowy projekt i zamień kod ViewController.swift na następujący.
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 jednego klucza w powyższym kodzie, która umożliwia usuwanie wierszy, jest ostatnią. Tutaj jeszcze raz do 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.
}
}
Dodaj UITableView
kontroler widoku w serii ujęć. Użyj automatycznego układu, aby przypiąć cztery strony widoku tabeli do krawędzi kontrolera widoku. Kontroluj przeciąganie z widoku tabeli w serii ujęć do @IBOutlet var tableView: UITableView!
linii w kodzie.
To wszystko. Powinieneś być teraz w stanie uruchomić aplikację i usunąć wiersze, przesuwając palcem w lewo i stukając „Usuń”.
Zmień tekst przycisku „Usuń”
Dodaj następującą metodę:
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Erase"
}
Niestandardowe akcje przycisków
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]
}
Pamiętaj, że jest to dostępne tylko w systemie iOS 8. Aby uzyskać więcej informacji, zobacz tę odpowiedź .
Zaktualizowano dla iOS 11
Działania można umieszczać na początku lub na końcu komórki za pomocą metod dodanych do interfejsu API UITableViewDelegate w 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
jednego , jest to całkowicie samodzielny projekt i nie trzeba robić niczego, co nie jest opisane tutaj. Powodem, dla którego zacząłem ustawiać go w kodzie jest to, że wymaga mniej wyjaśnień w moich odpowiedziach. Powinienem wrócić i edytować podstawowy przykład, aby użyć kodu.
Ten kod pokazuje, jak zaimplementować usuwanie.
#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 zastąpieniu inicjalizacji dodaj wiersz poniżej, aby wyświetlić pozycję przycisku Edytuj:
self.navigationItem.leftBarButtonItem = self.editButtonItem;
Miałem problem, który właśnie rozwiązałem, dlatego dzielę się nim, ponieważ może komuś pomóc.
Mam UITableView i dodałem pokazane metody, aby umożliwić przeciągnięcie, aby usunąć:
- (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 umożliwia wybór wielu elementów. Aby to zrobić, dodałem kod z próbki Apple TableMultiSelect . Gdy już działałem, stwierdziłem, że funkcja machnięcia usuwania przestała działać.
Okazuje się, że problem polegał na dodaniu następującego wiersza do viewDidLoad:
self.tableView.allowsMultipleSelectionDuringEditing = YES;
Po włączeniu tej linii multiselekty działałyby, ale przesunięcie palcem po usunięciu nie działało. Bez linii było odwrotnie.
Poprawka:
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), powinieneś użyć:
[self setEditing:YES animated:YES];
zamiast:
[self.tableView setEditing:YES animated:YES];
Oznacza to, że wielokrotny wybór jest aktywny tylko wtedy, gdy tabela jest w trybie edycji.
Poniżej UITableViewDataSource pomoże Ci usunąć przeciągnięcie
- (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 ponownie ładuje tableView
Szybki
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()
}
}
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]
}
Odpowiedź @ Kurbza jest niesamowita, ale chcę zostawić tę notatkę i mam nadzieję, że ta odpowiedź może zaoszczędzić ludziom trochę czasu.
Czasami miałem te linie w moim 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 przeciągania nie działa. Możesz używać tylko UITableViewCellEditingStyleDelete
, co jest stylem domyślnym.
Szybki 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]
}
Można to również osiągnąć w SWIFT, stosując następującą metodę
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
testArray.removeAtIndex(indexPath.row)
goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
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()
}
}
Wiem, że to stare pytanie, ale odpowiedź @Kurbz potrzebuje tego tylko dla Xcode 6.3.2 i SDK 8.3
Potrzebuję dodać [tableView beginUpdates]
i [tableView endUpdates]
(dzięki @ bay.phillips tutaj )
// 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];
}
Kiedy usuwasz komórkę widoku tabeli, musisz również usunąć obiekt tablicy o indeksie x.
Myślę, że możesz to 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 przeładować użycie widoku tabeli. Dodaj następujący wiersz w kodzie:
[tableView reloadData];
następnie pomyślnie usunąłeś wiersz. Po ponownym załadowaniu widoku lub dodaniu danych do źródła danych obiekt już tam nie będzie.
Dla wszystkich pozostałych odpowiedź Kurbza jest poprawna.
Chciałem tylko przypomnieć, że funkcja delegowania nie wystarczy, jeśli chcesz usunąć obiekt z tablicy DataSource.
Mam nadzieję, że ci pomogłem.
[tableView reloadData]
dzwonić [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]
}
W przypadku Swift po prostu napisz ten kod
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
print("Delete Hit")
}
}
Dla celu C po prostu napisz ten kod
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(@"index: %@",indexPath.row);
}
}
dla kodu swift4, najpierw włącz edycję:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
następnie dodajesz akcję usuwania do edytowanego delegata:
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
Aby usunąć komórkę po przeciągnięciu, istnieją dwie wbudowane metody UITableView. Napisz tę metodę w rozszerzeniu TableS dataSource.
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
}
Jeśli adoptujesz różne źródła danych, musisz przenieść wywołania zwrotne delegatów do UITableViewDiffableDataSource
podklasy. Na przykład:
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)
}
}
}
}