UITableViewCell, показать кнопку Удалить на салфетки

Как получить кнопку удаления, чтобы показать при прокрутке на UITableViewCell? Событие никогда не вызывается, и кнопка Удалить никогда не появляется.

17 ответов


во время запуска в (-viewDidLoad or in storyboard) do:

self.tableView.allowsMultipleSelectionDuringEditing = NO;

переопределение для поддержки условного редактирования представления таблицы. Это нужно только реализовать, если вы собираетесь возвращаться NO для некоторых элементов. По умолчанию все элементы доступны для редактирования.

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

этот ответ был обновлен до Swift 3

Я всегда думаю, что хорошо иметь очень простой, самодостаточный пример, чтобы ничего не предполагалось, когда я изучаю новую задачу. Этот ответ заключается в том, что для удаления UITableView строк. Проект работает следующим образом:

enter image description here

этот проект основан на пример UITableView для Swift.

добавить код

создать новый проект и заменить ViewController.SWIFT-код со следующим.

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

}

метод с одним ключом в приведенном выше коде, который позволяет удалять строки, является последним. Вот опять для ударения:

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

раскадровка

добавить UITableView в-представление-контроллер в раскадровке. Используйте auto layout, чтобы прикрепить четыре стороны представления таблицы к краям контроллера вида. Управление перетаскиванием из представления таблицы в раскадровке в @IBOutlet var tableView: UITableView! строки в код.

закончил

вот и все. Вы должны иметь возможность запускать приложение сейчас и удалять строки, проводя влево и нажав "удалить".


варианты

изменить текст кнопки "Удалить"

enter image description here

добавить следующий метод:

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

пользовательские действия кнопки

enter image description here

добавить следующая методика.

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

обратите внимание, что это доступно только из iOS 8. См.ответ для получения более подробной информации.

обновлено для iOS 11

действия могут быть размещены либо в начале, либо в конце ячейки с помощью методов, добавленных в API UITableViewDelegate в 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])
 }

более дальнеишее чтение


этот код показывает, как реализовать удаление.

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

при необходимости в переопределении инициализации добавьте строку ниже, чтобы отобразить элемент кнопки редактирования:

self.navigationItem.leftBarButtonItem = self.editButtonItem;

Примечание: у меня недостаточно репутации, чтобы опубликовать комментарий в ответе от Kurbz.

ответ от Курбза правильный. Но у меня это никогда не получалось.

после некоторого расследования я понял, что swipe-to-delete происходит, когда не редактируется представление таблицы..

Я никогда не видел этого явно заявленного как такового. Если я не ошибаюсь, Я не нашел другого способа заставить его работать.

при редактировании, удалить и/или изменить порядок появится контроль.


у меня была проблема, которую мне только что удалось решить, поэтому я делюсь ею, поскольку это может помочь кому-то.

у меня есть UITableView и добавлены методы, показанные для включения салфетки для удаления:

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

Я работаю над обновлением, которое позволяет мне перевести таблицу в режим редактирования и включить multiselect. Для этого я добавил код от Apple TableMultiSelect образец. Как только я получил эту работу, я обнаружил, что моя салфетка функция удаления остановилась рабочий.

оказывается, что добавление следующей строки в viewDidLoad было проблемой:

self.tableView.allowsMultipleSelectionDuringEditing = YES;

С этой строкой в multiselect будет работать, но салфетки для удаления не будет. Без линии все было наоборот.

исправления:

добавьте в viewController следующий метод:

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

затем в вашем методе, который переводит таблицу в режим редактирования (например, с нажатия кнопки), вы должны использовать:

[self setEditing:YES animated:YES];

вместо:

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

Это означает, что эта функция активна только тогда, когда таблица находится в режиме редактирования.


ниже UITableViewDataSource поможет вам для салфетки удалить

- (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 является NSMutableArray, а затем перезагрузите tableView

Свифт

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

в iOS 8 и Swift 2.0 пожалуйста, попробуйте это,

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

ответ@Kurbz потрясающий, но я хочу оставить эту записку и надеюсь, что этот ответ может сэкономить людям некоторое время.

у меня иногда были эти строки в моем контроллере, и они сделали функцию прокрутки не работающей.

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

если вы используете UITableViewCellEditingStyleInsert или UITableViewCellEditingStyleNone в качестве стиля редактирования функция прокрутки не работает. Вы можете использовать только UITableViewCellEditingStyleDelete, который является стилем по умолчанию.


кроме того, это может быть достигнуто в Swift с помощью метода следующим образом

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if (editingStyle == UITableViewCellEditingStyle.Delete){
        testArray.removeAtIndex(indexPath.row)
        goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}

Swift 3

все, что вам нужно сделать, это включить эти две функции:

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

}

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

когда вы удаляете ячейку своего tableview, вам также нужно удалить объект array в индексе x.

Я думаю, вы можете удалить его, используя жест салфетки. Представление таблицы вызовет делегата:

- (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. Добавьте в код следующую строку:

[tableView reloadData];

после этого вы успешно удалили строку. И когда вы перезагружаете представление или добавляете данные в источник данных, объект больше не будет.

для всех остальных ответ от Kurbz правильный.

Я только хотел напомнить вам, что функции делегата будет недостаточно, если вы хотите удалить объект из массива источников данных.

надеюсь, я вам помог.


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

Я знаю, что это старый вопрос, но @Kurbz ответ просто нужен для Xcode 6.3.2 и SDK 8.3

мне нужно добавить [tableView beginUpdates] и [tableView endUpdates] (спасибо @bay.Филлипс!--6-->здесь)

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

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

для Swift просто напишите этот код

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

для Objective C просто напишите этот код

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
       if (editingStyle == UITableViewCellEditingStyleDelete) {           
            NSLog(@"index: %@",indexPath.row);
           }
}

для кода swift4 сначала включите редактирование:

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

затем вы добавляете действие удаления в делегат редактирования:

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