ios UITableViewCell,滑动时显示删除按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3309484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:25:55  来源:igfitidea点击:

UITableViewCell, show delete button on swipe

iosuitableviewcocoa-touchuikit

提问by TheLearner

How do I get the delete button to show when swiping on a UITableViewCell? The event is never raised and the delete button never appears.

在 上滑动时如何显示删除按钮UITableViewCell?永远不会引发该事件,也永远不会出现删除按钮。

回答by Kurbz

During startup in (-viewDidLoad or in storyboard)do:

在启动期间(-viewDidLoad or in storyboard)做:

self.tableView.allowsMultipleSelectionDuringEditing = NO;

Override to support conditional editing of the table view. This only needs to be implemented if you are going to be returning NOfor some items. By default, all items are editable.

覆盖以支持表视图的条件编辑。仅当您要返回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
    }    
}

回答by Suragch

This answer has been updated to Swift 3

此答案已更新到 Swift 3

I always think it is nice to have a very simple, self-contained example so that nothing is assumed when I am learning a new task. This answer is that for deleting UITableViewrows. The project performs like this:

我一直认为有一个非常简单的、自包含的例子是很好的,这样当我学习一项新任务时什么都不做。这个答案是删除UITableView行。该项目执行如下:

enter image description here

在此处输入图片说明

This project is based on the UITableView example for Swift.

该项目基于SwiftUITableView 示例

Add the Code

添加代码

Create a new project and replace the ViewController.swift code with the following.

创建一个新项目并将 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.
        }
    }

}

The single key method in the code above that enables row deletion is the last one. Here it is again for emphasis:

上面代码中启用行删除的单键方法是最后一个。这里再次强调:

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

故事板

Add a UITableViewto the View Controller in the storyboard. Use auto layout to pin the four sides of the table view to the edges of the View Controller. Control drag from the table view in the storyboard to the @IBOutlet var tableView: UITableView!line in the code.

将 a 添加UITableView到情节提要中的视图控制器。使用自动布局将表格视图的四个边固定到视图控制器的边缘。控制从故事板中的表格视图拖动到@IBOutlet var tableView: UITableView!代码中的行。

Finished

完成的

That's all. You should be able to run your app now and delete rows by swiping left and tapping "Delete".

就这样。您现在应该能够运行您的应用程序并通过向左滑动并点击“删除”来删除行。



Variations

变化

Change the "Delete" button text

更改“删除”按钮文本

enter image description here

在此处输入图片说明

Add the following method:

添加以下方法:

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

Custom button actions

自定义按钮操作

enter image description here

在此处输入图片说明

Add the following method.

添加以下方法。

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

Note that this is only available from iOS 8. See this answerfor more details.

请注意,这仅适用于 iOS 8。有关更多详细信息,请参阅此答案

Updated for iOS 11

针对 iOS 11 更新

Actions can be placed either leading or trailing the cell using methods added to the UITableViewDelegate API in iOS 11.

可以使用添加到 iOS 11 中 UITableViewDelegate API 的方法将操作放置在单元格的前导或尾随。

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

Further reading

进一步阅读

回答by ma11hew28

This code shows how to implement the 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];
    }
}

Optionally, in your initialization override, add the line below to show the Edit button item:

或者,在您的初始化覆盖中,添加以下行以显示“编辑”按钮项:

self.navigationItem.leftBarButtonItem = self.editButtonItem;

回答by Leon

I had a problem which I have just managed to solve so I am sharing it as it may help someone.

我有一个我刚刚设法解决的问题,所以我分享它,因为它可能对某人有所帮助。

I have a UITableView and added the methods shown to enable 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
    }    
}

I am working on an update that allows me to put the table into edit mode and enables multiselect. To do that I added the code from Apple's TableMultiSelectsample. Once I got that working I found that my swipe the delete function had stopped working.

我正在开发一个更新,它允许我将表置于编辑模式并启用多选。要做到这一点,我添加从苹果公司的代码TableMultiSelect样品。一旦我开始工作,我发现我的滑动删除功能已经停止工作。

It turns out that adding the following line to viewDidLoad was the issue:

事实证明,将以下行添加到 viewDidLoad 是问题所在:

self.tableView.allowsMultipleSelectionDuringEditing = YES;

With this line in, the multiselect would work but the swipe to delete wouldn't. Without the line it was the other way around.

有了这一行,多选会起作用,但滑动删除不会。没有这条线,情况正好相反。

The fix:

修复:

Add the following method to your viewController:

将以下方法添加到您的视图控制器:

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

Then in your method that puts the table into editing mode (from a button press for example) you should use:

然后在您将表格置于编辑模式的方法中(例如通过按下按钮),您应该使用:

[self setEditing:YES animated:YES];

instead of:

代替:

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

This means that multiselect is only enabled when the table is in editing mode.

这意味着只有在表格处于编辑模式时才启用多选。

回答by iAnkit

Below UITableViewDataSource will help you for swipe delete

下面的 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];
    }
}

arrYearsis a NSMutableArray and then reload the tableView

arrYears是一个 NSMutableArray 然后重新加载 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()
    }
}

回答by Masa S-AiYa

In iOS 8 and Swift 2.0 please try this,

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

回答by Brian

@Kurbz's answer is awesome, but I want to leave this note and hope this answer can save people some time.

@Kurbz 的回答很棒,但我想留下这个笔记,希望这个回答可以为人们节省一些时间。

I occasionally had these lines in my controller, and they made the swiping feature not working.

我的控制器中偶尔会有这些线条,它们使滑动功能不起作用。

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

If you use UITableViewCellEditingStyleInsertor UITableViewCellEditingStyleNoneas the editing style, then the swiping feature doesn't work. You can only use UITableViewCellEditingStyleDelete, which is the default style.

如果您使用UITableViewCellEditingStyleInsertUITableViewCellEditingStyleNone作为编辑样式,则滑动功能不起作用。您只能使用UITableViewCellEditingStyleDelete,这是默认样式。

回答by Pratik Lad

Swift 4

斯威夫特 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]
}

回答by DrPatience

Also, this can be achieved in SWIFT using the method as follows

此外,这可以使用以下方法在 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)
    }
}

回答by Machado

Swift 3

斯威夫特 3

All you have to do is enable these two functions:

您所要做的就是启用这两个功能:

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

}