【问题标题】:How to enable swipe to delete cell in a TableView?如何启用滑动以删除 TableView 中的单元格?
【发布时间】:2012-02-17 11:29:47
【问题描述】:

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

我应该怎么做。

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

仍然没有滑动功能。

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

还是我错过了什么?

【问题讨论】:

  • 参考链接,对你有帮助,stackoverflow.com/questions/3309484/…
  • 我已经覆盖了 commitEditingStyle 并将 Editing 设置为 YES,现在我也覆盖了 CanEditRowAtIndexPath。正常编辑控件出现在单击删除按钮时。但不是在刷卡!是不是因为我的类是 UIViewController 的子类,并且只实现了委托和数据源方法,而不是 UITableViewController 可能正在做一些事情来启用滑动手势。
  • 我昨天刚刚在 UIViewController 中将 UITableView 设置为 IBOutlet,并且完全按照我展示的帖子进行操作,我已经滑动删除。所以我可以说你不需要启用滑动手势,但如果你真的不能让它以任何其他方式工作,你可能不得不求助于它。
  • 顺便说一句,问题已经解决,我实际上已经覆盖了 editingStyleForRowAtIndexPath 并且当表不处于编辑模式时它返回 None ,这就是问题所在。我为之前正在做的事情添加了该方法,但在需求发生变化时忘记将其删除。

标签: ios uitableview uiswipegesturerecognizer


【解决方案1】:

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

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

【讨论】:

  • 你删除了[tableView setEditing:YES];吗?
  • 如果我删除它,基本的删除按钮根本不会出现!
  • 如果您不删除它,您会将表格置于无法滑动的编辑状态。它要么是左侧的圆形红色减号按钮,要么是滑动,而不是一起滑动。
  • 现在我已经删除了 setEditing 语句,但是当我滑动时没有任何反应。是不是因为我使用的是 UIViewController 而不是 TabelViewController,它可能会在默认情况下向每个单元格添加滑动手势。
  • 我想补充一点,tableView:canEditRowAtIndexPath: 可能还不够。您还必须实现tableView:commitEditingStyle:forRowAtIndexPath
【解决方案2】:

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

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

【讨论】:

  • 不适合我 :( 是因为我的类是 UIViewController 的子类,我需要做一些 UITabelViewController 做的额外事情吗?
  • @AmoghTalpallikar,您是如何解决问题的?你能发布你的解决方案吗?我也有同样的问题。另外我的类是 UIViewController 的子类,我的 tableView 的所有单元格都是 UITableViewCell 的子类。
【解决方案3】:

Kyr Dunenkoff聊天的结论是

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

}

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 我刚刚在 iPhone 6 上的 iOS 8.1.2 中对此进行了测试,并且可以正常工作。我只需要实现- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 方法,因为默认情况下编辑应该是YES。
    【解决方案5】:
    // 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】:

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

    【讨论】:

    • 嗯,这个答案当然是给正在寻找答案的其他人的。 :)
    【解决方案7】:

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

    只需将抽屉控制器中的手势识别器配置为不响应侧面抽屉中的关闭手势,就可以在我的电视中使用滑动删除操作。

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

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

    【讨论】:

    • 我知道这很旧,但我在使用 MMDrawerController 时遇到了同样的问题。您能否详细说明“将抽屉控制器中的手势识别器配置为不响应侧面抽屉中的关闭手势允许滑动删除以在我的电视中工作”。你是怎么做到的?
    【解决方案8】:
    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];
        }
    }
    

    【讨论】:

      【解决方案9】:

      这是快速版本

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

      【讨论】:

        【解决方案10】:

        请快速尝试此代码,

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

        【讨论】:

          【解决方案11】:

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

          【讨论】:

            【解决方案12】:

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

            self.tableView.editing = NO;

            【讨论】:

              【解决方案13】:

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

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

              【讨论】:

                猜你喜欢
                • 2018-11-12
                • 2014-11-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多