UITableView 禁用滑动删除,但在编辑模式下仍然有删除?

我想要一些类似于报警应用程序,在这里你不能滑动删除行,但你仍然可以在编辑模式下删除行。

当注释掉 tableView: committee EditingStyle: forRowAtIndexPath: 时,我禁用了要删除的滑动操作,并且在编辑模式下仍然有删除按钮,但是当我按 Delete 按钮时会发生什么。叫什么?

77584 次浏览

Basically, you enable or disable editing using the methods

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

If editing is enabled, the red deletion icon appears, and a delete conformation requested to the user. If the user confirms, the delegate method

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

is notified of the delete request. If you implement this method, then swipe to delete is automatically made active. If you do not implement this method, then swipe to delete is not active, however you are not able to actually delete the row. Therefore, to the best of my knowledge, you can not achieve what you asked for, unless using some undocumented, private APIs. Probably this is how the Apple application is implemented.

Ok, it turns out to be quite easy. This is what I did to solve this:

Objective-C

- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Detemine if it's in editing mode
if (self.tableView.editing)
{
return UITableViewCellEditingStyleDelete;
}


return UITableViewCellEditingStyleNone;
}

Swift 2

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
if tableView.editing {
return .Delete
}


return .None
}

Swift 3

override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
if tableView.isEditing {
return .delete
}


return .none
}

You still need to implement tableView:commitEditingStyle:forRowAtIndexPath: to commit the deletion.

Just to make things clear, swipe-to-delete will not be enabled unless tableView:commitEditingStyle:forRowAtIndexPath: is implemented.

While I was in development, I didn't implement it, and therefore swipe-to-delete wasn't enabled. Of course, in a finished app, it would always be implemented, because otherwise there would be no editing.

Swift Version:

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {


if(do something){


return UITableViewCellEditingStyle.Delete or UITableViewCellEditingStyle.Insert


}
return UITableViewCellEditingStyle.None


}

On C#:

I had the same issue where it was needed to enable/disable rows with Delete option on swipe. Multiple rows needed to be swiped left and get deleted, keep them in another colour. I achieved using this logic.

[Export("tableView:canEditRowAtIndexPath:")]
public bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{


if (deletedIndexes.Contains(indexPath.Row)){
return false;
}
else{
return true;
}


}

Note that deletedIndexes are a list of indexes which are deleted from the table without duplicates. This code check whether a row is deleted, then it disables swipe or vice versa.

The equivalent delegate function is Swift is canEditRowAtIndexPath.

You need to implement the CanEditRowAt function.

You can return .delete in the EditingStyleForRowAt function so you can still delete in editing mode.

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


func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}

I came across this problem either and fixed with codes below. hope it will help you.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {


BOOL deleteBySwipe = NO;
for (UIGestureRecognizer* g in tableView.gestureRecognizers) {
if (g.state == UIGestureRecognizerStateEnded) {
deleteBySwipe = YES;
break;
}
}


if (deleteBySwipe) {
//this gesture may cause delete unintendedly
return;
}
//do delete
}

}