Ios UITableViewCell,滑动时显示删除按钮

Ios UITableViewCell,滑动时显示删除按钮,ios,uitableview,cocoa-touch,uikit,Ios,Uitableview,Cocoa Touch,Uikit,如何在滑动UITableViewCell时显示删除按钮?事件不会引发,删除按钮也不会出现。在(-viewdiload或storyboard)中启动时执行以下操作: self.tableView.allowsMultipleSelectionDuringEditing = NO; 替代以支持表视图的条件编辑。仅当您要为某些项目返回NO时,才需要实现此功能。默认情况下,所有项目都是可编辑的 - (BOOL)tableView:(UITableView *)tableView canEditRowA

如何在滑动
UITableViewCell
时显示删除按钮?事件不会引发,删除按钮也不会出现。

(-viewdiload或storyboard)中启动时执行以下操作:

self.tableView.allowsMultipleSelectionDuringEditing = NO;
替代以支持表视图的条件编辑。仅当您要为某些项目返回
NO
时,才需要实现此功能。默认情况下,所有项目都是可编辑的

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you 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) {
        //add code here for when you hit delete
    }    
}

删除tableview的单元格时,还必须删除索引x处的数组对象

我想你可以用刷卡的姿势把它移走。 表视图将调用委托:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //add code here for when you hit delete
        [dataSourceArray removeObjectAtIndex:indexPath.row];
    }    
}
移除对象后。您必须重新加载使用的tableview。 在代码中添加以下行:

[tableView reloadData];
之后,您已成功删除该行。当您重新加载视图或向数据源添加数据时,对象将不再存在

对于所有其他问题,Kurbz的答案都是正确的

我只是想提醒您,如果要从数据源数组中删除对象,委托函数是不够的


我希望我已经帮了你。

我遇到了一个问题,我刚刚设法解决了,所以我分享它,因为它可能会帮助别人

我有一个UITableView,并添加了所示的方法,以允许滑动删除:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you 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) {
        //add code here for when you hit delete
    }    
}
我正在进行更新,该更新允许我将表格置于编辑模式并启用multiselect。为此,我添加了来自苹果示例的代码。一旦我开始工作,我发现我的滑动删除功能已经停止工作

事实证明,将以下行添加到viewDidLoad是问题所在:

self.tableView.allowsMultipleSelectionDuringEditing = YES;
有了这一行,multiselect就可以工作了,但是滑动删除就不行了。没有电话线,情况正好相反

修复方法:

将以下方法添加到viewController:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    self.tableView.allowsMultipleSelectionDuringEditing = editing; 
    [super setEditing:editing animated:animated];
}
然后,在将表格置于编辑模式的方法中(例如,通过按下按钮),您应该使用:

[self setEditing:YES animated:YES];
而不是:

[self.tableView setEditing:YES animated:YES];

这意味着multiselect仅在表格处于编辑模式时启用。

此代码显示了如何实现删除

#pragma mark - UITableViewDataSource

// Swipe to delete.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_chats removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}
(可选)在初始化覆盖中,添加以下行以显示编辑按钮项:

self.navigationItem.leftBarButtonItem = self.editButtonItem;

下面的UITableViewDataSource将帮助您进行刷卡删除

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [arrYears removeObjectAtIndex:indexPath.row];
        [tableView reloadData];
    }
}
是一个NSMutableArray,然后重新加载tableView

Swift

 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
            return true
        }

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyleDelete {
        arrYears.removeObjectAtIndex(indexPath.row)
        tableView.reloadData()
    }
}

@Kurbz的答案非常棒,但我想留下这张便条,希望这个答案能为人们节省一些时间

我的控制器中偶尔会有这些线路,它们使刷卡功能无法工作

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewCellEditingStyleNone; 
}

如果使用
UITableViewCellEditingStyleInsert
UITableViewCellEditingStyleNone
作为编辑样式,则滑动功能不起作用。您只能使用默认样式
UITableViewCellEditingStyleDelete

此外,可以使用以下方法在SWIFT中实现此功能

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if (editingStyle == UITableViewCellEditingStyle.Delete){
        testArray.removeAtIndex(indexPath.row)
        goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}

我知道这是一个老问题,但@Kurbz answer只需要在Xcode 6.3.2和SDK 8.3中使用这个

我需要添加
[tableView开始更新]
[tableView结束更新]
(感谢@bay.phillips)


在iOS 8和Swift 2.0中,请尝试此功能

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, commitEdittingStyle 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]
}
Swift 2.2:

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

override func tableView(tableView: UITableView,
    editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "DELETE"){(UITableViewRowAction,NSIndexPath) -> Void in

    print("Your action when user pressed delete")
}
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "EDIT"){(UITableViewRowAction,NSIndexPath) -> Void in

    print("Your action when user pressed edit")
}
    return [delete, block]
}
此答案已更新为Swift 3

我一直认为有一个非常简单、自包含的例子是很好的,这样在我学习一项新任务时就不会假设任何东西。这个答案就是删除
UITableView
行。该项目执行如下操作:

这个项目是基于

添加代码 创建新项目并用以下代码替换ViewController.swift代码

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // These strings will be the data for the table view cells
    var animals: [String] = ["Horse", "Cow", "Camel", "Pig", "Sheep", "Goat"]

    let cellReuseIdentifier = "cell"

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // It is possible to do the following three things in the Interface Builder
        // rather than in code if you prefer.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }

    // number of rows in table view
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.animals.count
    }

    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!

        cell.textLabel?.text = self.animals[indexPath.row]

        return cell
    }

    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You tapped cell number \(indexPath.row).")
    }

    // this method handles row deletion
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == .delete {

            // remove the item from the data model
            animals.remove(at: indexPath.row)

            // delete the table view row
            tableView.deleteRows(at: [indexPath], with: .fade)

        } else if editingStyle == .insert {
            // Not used in our example, but if you were adding a new row, this is where you would do it.
        }
    }

}
上面代码中支持行删除的单键方法是最后一个。这里再次强调:

// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

        // remove the item from the data model
        animals.remove(at: indexPath.row)

        // delete the table view row
        tableView.deleteRows(at: [indexPath], with: .fade)

    } else if editingStyle == .insert {
        // Not used in our example, but if you were adding a new row, this is where you would do it.
    }
}
故事板 将
UITableView
添加到情节提要中的视图控制器。使用“自动布局”将表格视图的四边固定到视图控制器的边缘。控制从情节提要中的表视图拖动到
@IBOutlet var tableView:UITableView代码中的行

完成了 就这些。您现在应该可以运行应用程序并通过向左滑动并点击“删除”来删除行


变化 更改“删除”按钮文本

 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
            return true
        }

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyleDelete {
        arrYears.removeObjectAtIndex(indexPath.row)
        tableView.reloadData()
    }
}

添加以下方法:

func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
    return "Erase"
}
自定义按钮操作

添加以下方法

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    // action one
    let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
        print("Edit tapped")
    })
    editAction.backgroundColor = UIColor.blue

    // action two
    let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
        print("Delete tapped")
    })
    deleteAction.backgroundColor = UIColor.red

    return [editAction, deleteAction]
}
请注意,这仅适用于iOS 8。有关更多详细信息,请参阅

为iOS 11更新

使用iOS 11中添加到UITableViewDelegate API的方法,可以将操作置于单元格的前面或后面

func tableView(_ tableView: UITableView,
                leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
 {
     let editAction = UIContextualAction(style: .normal, title:  "Edit", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
             success(true)
         })
editAction.backgroundColor = .blue

         return UISwipeActionsConfiguration(actions: [editAction])
 }

 func tableView(_ tableView: UITableView,
                trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
 {
     let deleteAction = UIContextualAction(style: .normal, title:  "Delete", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
         success(true)
     })
     deleteAction.backgroundColor = .red

     return UISwipeActionsConfiguration(actions: [deleteAction])
 }
进一步阅读

    • 对于Swift,只需编写以下代码

      func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
              if editingStyle == .Delete {
                  print("Delete Hit")
              }
      }
      
      对于目标C,只需编写以下代码

      - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
             if (editingStyle == UITableViewCellEditingStyleDelete) {           
                  NSLog(@"index: %@",indexPath.row);
                 }
      }
      
      斯威夫特3 您只需启用这两个功能:

      func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
      
          return true
      
      }
      
      func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
      
          if editingStyle == UITableViewCellEditingStyle.delete {
              tableView.reloadData()
          }
      
      }
      

      Swift 4

      func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
          let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
              // delete item at indexPath
          tableView.deleteRows(at: [indexPath], with: .fade)
      
          }
          return [delete]
      }
      

      对于swift4代码,首先启用编辑:

      func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
          return true
      }
      
      然后将删除操作添加到编辑代理:

      func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
          let action = UITableViewRowAction(style: .destructive, title: "Delete") { (_, index) in
              // delete model object at the index
              self.models[index.row]
              // then delete the cell
              tableView.beginUpdates()
              tableView.deleteRows(at: [index], with: .automatic)
              tableView.endUpdates()
      
          }
          return [action]
      }
      
      Swift 4,5

      要在刷卡时删除单元格,UITableView有两个内置方法。请在TableView数据源扩展中编写此方法

      func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let delete = deleteProperty(at: indexPath)
        return UISwipeActionsConfiguration(actions: [delete])
      }
      
      // Declare this method in UIViewController Main and modify according to your need
      
      func deleteProperty(at indexpath: IndexPath) -> UIContextualAction {
        let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completon) in
          self.yourArray.remove(at: indexpath) // Removing from array at selected index
      
          completon(true)
          action.backgroundColor = .red //cell background color
        }
        return action
      }
      

      如果要采用diffable数据源,则必须将委托回调移动到
      UITableViewDiffableDataSource
      子类。例如:

      class DataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
      
          override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
              return true
          }
      
          override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
              if editingStyle == .delete {
                  if let identifierToDelete = itemIdentifier(for: indexPath) {
                      var snapshot = self.snapshot()
                      snapshot.deleteItems([identifierToDelete])
                      apply(snapshot)
                  }
              }
          }
      }
      
      类数据源:UITableViewDiffableDataSource{
      重写func tableView(tableView:UITableView,canEditRowAt indexath:indexPath)->Bool{
      返回真值
      }
      重写func tableView(tableView:UITableView,commit editingStyle:UITableViewCell.editingStyle,forRowAt indepath:indepath){
      如果editingStyle==.delete{
      如果let identifierToDelete=itemIdentifier(for:indexPath){
      var snapshot=self.snapshot()
      snapshot.deleteItems([identifierToDelete])
      应用(快照)
      }
      }
      }
      }
      
      这很有效,
      class DataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
      
          override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
              return true
          }
      
          override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
              if editingStyle == .delete {
                  if let identifierToDelete = itemIdentifier(for: indexPath) {
                      var snapshot = self.snapshot()
                      snapshot.deleteItems([identifierToDelete])
                      apply(snapshot)
                  }
              }
          }
      }