简体   繁体   English

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

[英]How to enable swipe to delete cell in a TableView?

I have a UIViewController that implements TableViews delegate and datasource protocols. 我有一个UIViewController实现了TableViews委托和数据源协议。 Now I want to add "swipe to delete" gesture to cells. 现在我想向细胞添加“轻扫删除”手势。

How should I go about it. 我应该怎么做呢。

I have given a blank implementation of commitEditingStyle method and also set the Editing property to YES. 我给出了一个commitEditingStyle方法的空白实现,并将Editing属性设置为YES。

Still the swipe feature is not coming . 仍然没有滑动功能。

Now Do I need to separately add UISwipeGesture to each cell ? 现在我需要单独向每个单元格添加UISwipeGesture吗?

Or am I missing something ? 或者我错过了什么?

As Dan has commented above, you need to implement the following table view delegate methods: 正如Dan上面所述,您需要实现以下表视图委托方法:

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

Note: I have tried this in iOS 6 and iOS 7. 注意:我在iOS 6和iOS 7中尝试过这个。

- (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.");
}

You don't have to set editing:YES if you need to show Delete button on cell swipe. 您不必设置editing:YES如果您需要在单元格滑动上显示删除按钮,则为editing:YES You have to implement tableView:canEditRowAtIndexPath: and return YES from there for rows you need to edit/delete. 您必须实现tableView:canEditRowAtIndexPath:并从那里为您需要编辑/删除的行返回YES。 This is not necessary when your tableView's dataSource is a subclass of UITableViewContoller - this method, if not overridden, returns YES by default. 当tableView的dataSource是UITableViewContoller的子类时,这不是必需的 - 如果不覆盖此方法,则默认情况下返回YES。 In all other cases you have to implement it. 在所有其他情况下,您必须实现它。

EDIT: Together we have found the problem - tableView:editingStyleForRowAtIndexPath: returned UITableViewCellEditingStyleNone if table wasn't in editing mode. 编辑:我们一起发现了问题 - tableView:editingStyleForRowAtIndexPath:如果表未处于编辑模式,则返回UITableViewCellEditingStyleNone

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

Please try this code in swift, 请在swift中尝试此代码,

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

Try adding the following to your class: 尝试将以下内容添加到您的班级:

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

Conclusion of Kyr Dunenkoff chat is 结论Kyr Dunenkoff聊天是

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

}

should not be defined if you need delete button to appear on swipe. 如果您需要在滑动时显示删除按钮,则不应定义。

If you are using an NSFetchedResultsControllerDelegate to populate the table view, this worked for me: 如果您使用NSFetchedResultsControllerDelegate填充表视图,这对我NSFetchedResultsControllerDelegate

  • Make sure tableView:canEditRowAtIndexPath returns true always 确保tableView:canEditRowAtIndexPath始终返回true
  • In your tableView:commitEditingStyle:forRowAtIndexPath implementation, do not delete the row directly from the table view. tableView:commitEditingStyle:forRowAtIndexPath实现中,不要直接从表视图中删除该行。 Instead, delete it using your managed object context, eg: 而是使用您的托管对象上下文删除它,例如:

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

This was a problem for me too...I could only get swiping to delete to work once every 10 or so attempts. 对我来说这也是一个问题......我只能每10次左右尝试一次刷到删除工作。 It turns out the gesture on the TV was being blocked by another gesture in the parent view controller. 原来, gesture正在阻止在父视图控制器另一手势在电视机上。 The TV was nested in a MMDrawerController (swipe able drawer layout). 电视嵌套在MMDrawerController (可滑动的抽屉布局)中。

Just configuring the gesture recognizer in the drawer controller to not respond to close gestures in the flanking drawers allowed swipe to delete to work in my TV. 只是在抽屉控制器中配置手势识别器以不响应侧翼抽屉中的近距离手势,允许滑动删除以在我的电视中工作。

You could also try doing something like this with the gesture delegate : 您也可以尝试使用gesture delegate做类似的事情:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

This is the swift version 这是快速版本

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

根据我的经验,您似乎必须将UITableView editing设置为NO才能滑动才能工作。

self.tableView.editing = NO;

在iOS 8.0之后,您可以自定义您的操作

- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
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];
    }
}

You can see all necessary methods by creating a UITableViewController class (temporary) in XCode 5 and then copy which method you would like to use. 您可以通过在XCode 5中创建UITableViewController类(临时)来查看所有必需的方法,然后复制您要使用的方法。 Those methods you need will be commented out with pre-filled in lines you desire. 您需要的那些方法将用您想要的预先填充的行注释掉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM