当我在UITableViewCell上滑动时,如何让删除按钮显示出来?事件从未触发,删除按钮从未出现。
当我在UITableViewCell上滑动时,如何让删除按钮显示出来?事件从未触发,删除按钮从未出现。
在启动时的(-viewDidLoad或者在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
}
}
此答案已更新至Swift 3
我认为,在学习新任务时,拥有一个非常简单、自包含的示例是很好的,因为没有任何假设。这个答案就是删除UITableView行的示例。项目执行如下:
本项目基于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!。
就是这样。您现在应该可以运行您的应用程序,并通过向左滑动并点击“删除”来删除行。
更改“删除”按钮文本
添加以下方法:
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Erase"
}
自定义按钮操作
添加以下方法。
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])
}
这段代码演示了如何实现删除操作。
#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;
我遇到了一个问题,但刚刚解决了,所以想分享一下,说不定能帮到别人。
我有一个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];
这意味着只有当表格处于编辑模式时,多选才会被启用。
下面的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。
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()
}
}
在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 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]
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
testArray.removeAtIndex(indexPath.row)
goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
您所需要做的就是启用这两个函数:
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()
}
}
UITableViewCell创建滑动删除操作的不同方式。链接 - Imanou Petit