UITableViewCell,滑动时显示删除按钮

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

291386 次浏览

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

self.tableView.allowsMultipleSelectionDuringEditing = false

重写以支持表视图的条件编辑。只有当您要为某些项返回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
}
}

当你移除tableview的一个单元格时,你也必须移除索引x处的数组对象。

我认为你可以用滑动手势删除它。 表视图将调用Delegate:

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

之后,就成功删除了该行。当您重新加载视图或向DataSource添加数据时,对象将不再存在。

对于所有其他的,库尔茨的答案是正确的。

我只是想提醒你,如果你想从DataSource数组中删除对象,委托函数是不够的。

我希望我对你有所帮助。

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

我有一个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
}
}

我正在进行更新,使我可以将表设置为编辑模式并启用多选。为此,我添加了来自苹果TableMultiSelect示例的代码。当我开始工作时,我发现我的滑动删除功能已经停止工作。

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

self.tableView.allowsMultipleSelectionDuringEditing = YES;

有了这一行,多选可以工作,但滑动删除就不行了。没有这条线,情况正好相反。

解决办法:

添加以下方法到你的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];

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

这段代码展示了如何实现删除。

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

可选地,在初始化覆盖中,添加下面的行来显示Edit按钮项:

self.navigationItem.leftBarButtonItem = self.editButtonItem;
- (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];
}
}

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

# EYZ0 # EYZ1

斯威夫特

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

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

我的控制器中偶尔会出现这些线条,它们会导致滑动功能无法工作。

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

如果你使用UITableViewCellEditingStyleInsertUITableViewCellEditingStyleNone作为编辑样式,那么滑动功能就不起作用了。您只能使用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)
}
}

我知道这是一个老问题,但是@Kurbz的答案只需要Xcode 6.3.2和SDK 8.3

我需要添加[tableView beginUpdates][tableView endUpdates](感谢@bay。菲利普斯# EYZ2)

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

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

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 3

我总是认为有一个非常简单的、独立的例子是很好的,这样当我学习一个新任务时,就不会假设任何事情。这个答案是用于删除UITableView行。项目执行如下所示:

enter image description here

这个项目是基于Swift的UITableView示例

添加代码

创建一个新项目,用以下代码替换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。使用自动布局将表视图的四个边固定到视图控制器的边缘。控件从故事板中的表视图拖动到代码中的@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更新

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

进一步的阅读

对于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);
}
}

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


}

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

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

< >强劲迅速4、5 < / >强

要在滑动中删除单元格,UITableView有两个内置的方法。把这个方法写在TableView dataSource扩展中。

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = deleteProperty(at: indexPath)
return UISwipeActionsConfiguration(actions: [delete])
}


// Declare this method in UIViewController 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
}

如果采用可变数据源,则必须将委托回调移动到UITableViewDiffableDataSource子类。例如:

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

SWIFT 5:适用于iOS 13+

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

    

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {  (contextualAction, view, boolValue) in
//Code I want to do here
}
        

let editAction = UIContextualAction(style: .destructive, title: "Edit") {  (contextualAction, view, boolValue) in
//Code I want to do here
}
        

let swipeActions = UISwipeActionsConfiguration(actions: [deleteAction, editAction])
        

return swipeActions
}