如何启用滑动删除 TableView 中的单元格?

我有 实现 TableView 委托和数据源的 UIViewController协议。 现在我想添加“滑动删除”手势到细胞。

我该怎么做。

我给出了一个空白的 commitEditingStyle方法的实现,并且将 Editing 属性设置为 YES。

还是没有刷卡功能。

现在我是否需要分别向每个单元格添加 UISwipeGesture

还是我错过了什么?

86330 次浏览

如果需要在单元格滑动时显示“删除”按钮,则不必设置 editing:YES。对于需要编辑/删除的行,必须实现 tableView:canEditRowAtIndexPath:并从中返回 YES。当 tableView 的 dataSource 是 UITableViewContoller 的子类时,这是不必要的——如果没有重写,该方法默认返回 YES。在所有其他情况下,您都必须实现它。

编辑: 我们一起发现了问题——如果表不处于编辑模式,tableView:editingStyleForRowAtIndexPath:返回 UITableViewCellEditingStyleNone

尝试将以下内容添加到您的类中:

// Override to support conditional editing of the table view.
- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return(YES);
}

Kyr Dunenkoff聊天的结论是

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {


}

不应该被定义,如果你需要删除按钮出现在滑动。

正如上面的 所述,您需要实现以下表视图委托方法:

  1. tableView:canEditRowAtIndexPath:
  2. tableView:commitEditingStyle:forRowAtIndexPath:

注意: 我已经在 iOS6和 iOS7中尝试过了。

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return YES - we will be able to delete all rows
return YES;
}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Perform the real delete action here. Note: you may need to check editing style
//   if you do not perform delete only.
NSLog(@"Deleted row.");
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not 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) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

通过在 XCode 5中创建一个 UITableViewController 类(临时) ,然后复制您想要使用的方法,您可以看到所有必要的方法。您需要的那些方法将被注释掉,并预先填充您想要的行。

这对我来说也是一个问题... 我只能得到滑动删除工作每10左右尝试一次。原来电视机上的 gesture被父视图控制器中的另一个手势屏蔽了。电视是嵌套在一个 MMDrawerController(可滑动抽屉布局)。

只要配置手势识别器在抽屉控制器不响应关闭手势在侧面抽屉允许滑动删除工作在我的电视。

你也可以尝试用 gesture delegate做类似的事情:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
NSMutableArray *post= [NSMutableArray alloc]initWithObject:@"1",@"2",@"3",nil];




- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {


NSUInteger row = [indexPath row];
NSUInteger count = [posts count];


if (row < count) {
return UITableViewCellEditingStyleDelete;
} else {
return UITableViewCellEditingStyleNone;
}
}


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


NSUInteger row = [indexPath row];
NSUInteger count = [posts count];


if (row < count) {


[posts removeObjectAtIndex:row];
}
}

这是最快的版本

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}


// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

请迅速尝试此代码,

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

如果您使用 NSFetchedResultsControllerDelegate来填充表视图,这对我来说很有效:

  • 确保 tableView:canEditRowAtIndexPath始终返回 true
  • tableView:commitEditingStyle:forRowAtIndexPath实现中,不要直接从表视图中删除该行。相反,使用托管对象上下文删除它,例如:

    if editingStyle == UITableViewCellEditingStyle.Delete {
    let word = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Word
    self.managedObjectContext.deleteObject(word)
    self.saveManagedObjectContext()
    }
    
    
    func saveManagedObjectContext() {
    do {
    try self.managedObjectContext.save()
    } catch {
    let saveError = error as NSError
    print("\(saveError), \(saveError.userInfo)")
    }
    }
    

在我的经验,似乎你必须有 editingUITableView设置为 NO刷新工作。

self.tableView.editing = NO;

在 iOS 8.0之后,您可以在

- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath