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


75

我有一个UIViewController实现TableViews委托和数据源协议的。现在,我想向单元格添加“滑动删除”手势。

我应该怎么做。

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

仍然没有滑动功能。

现在我需要分别添加UISwipeGesture到每个单元格吗?

还是我错过了什么?


请参阅链接,它可能对您有帮助,stackoverflow.com
questions/3309484/…

2
我已经覆盖了commitEditingStyle,并将Editing设置为YES,现在我也已经覆盖了CanEditRowAtIndexPath。出现普通的Edit控件,单击“删除”按钮即会出现。但是不要刷卡!是因为My类是UIViewController的子类,并且仅实现委托和数据源方法,而不实现UITableViewController的方法,后者可能在做某些操作以启用滑动手势。
Amogh Talpallikar,2012年

昨天我刚刚在UIViewController中将UITableView设置为IBOutlet,然后按照我显示的帖子进行操作,然后滑动即可删除。因此,我可以说您不需要启用滑动手势,尽管如果您确实无法使它以任何其他方式工作,则可能必须诉诸于此。
gurooj 2012年

顺便说一句,问题解决了,我实际上已经覆盖了editingStyleForRowAtIndexPath,当表未处于编辑模式时,它返回None,这就是问题所在。我为以前所做的事情添加了该方法,但是在需求更改时忘记将其删除。
Amogh Talpallikar,2012年

Answers:


55

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

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


你删除了[tableView setEditing:YES];吗?
Kyr Dunenkoff

如果删除它,根本没有删除按钮!
Amogh Talpallikar,2012年

3
如果不删除它,则将表格置于无法滑动的编辑状态。它要么是左侧的圆形红色减号按钮,要么是滑动(不是一起)。
Kyr Dunenkoff 2012年

1
现在,我删除了setEditing语句,但是滑动时没有任何反应。是因为我使用的是UIViewController而不是TabelViewController,它可能默认将滑动手势添加到每个单元格。
Amogh Talpallikar,2012年

5
我要补充一点,tableView:canEditRowAtIndexPath:可能还不够。您还必须实现tableView:commitEditingStyle:forRowAtIndexPath
Dan Loewenherz

61

正如Dan在上面评论的那样,您需要实现以下表视图委托方法:

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

注意:我已经在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.");
}

3
我刚刚在iPhone 6的iOS 8.1.2中对此进行了测试,并且可以正常工作。我只需要实现该- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath方法,因为默认情况下编辑应为YES。
克莱默2015年

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

6
对像我这样的新手来说值得注意/评论:该行仍需要删除,并且数据源(例如数组)需要减少。
BananaAcid 2014年

12

请尽快尝试此代码,

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

5

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

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

5
不为我工作:(是因为我的类是UIViewController的子类,并且我需要做UITabelViewController所做的其他事情吗?
Amogh Talpallikar 2012年

1
@AmoghTalpallikar,您如何解决您的问题?您可以发布解决方案吗?我也有同样的问题。另外,我的类是UIViewController的子类,而tableView的所有单元格都是UITableViewCell的子类。
Shamsiddin

3

Kyr Dunenkoff聊天的结论是

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

}

如果需要在删除时显示删除按钮,则不应定义。


1

如果您使用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)")
        }
    }
    

0

这是快速版本

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

0

这对我来说也是个问题...每10次尝试我只能滑动一次才能删除以工作。事实证明,gesture电视被父视图控制器中的另一个手势阻止了。电视被嵌套在MMDrawerController(可滑动滑动的抽屉布局)中。

只需在抽屉控制器中配置手势识别器,使其不对侧面抽屉中的关闭手势做出响应,就可以在我的电视上进行滑动删除操作。

您也可以尝试使用gesture delegate

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

我知道这很旧,但是MMDrawerController存在相同的确切问题。.您能否详细说明“在抽屉控制器中配置手势识别器以不响应侧面抽屉中的关闭手势,而允许在我的抽屉中进行滑动删除操作电视”。你是怎样做的?
标记

0

根据我的经验,好像你必须editingUITableView设置为NO用于刷卡的工作。

self.tableView.editing = NO;


0

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.