进入编辑模式 代码体现
// 设置 editing 属性 tableView?.editing = true // 这个设置的时候是有动画效果的 tableView.setEditing(true, animated: true) // 我一般喜欢的设置方式 (写在 btn 或者 item 的监听方法里面) // 实现编辑模式和非编辑模式的切换 tableView.editing = !tableView.editing tableView.setEditing(!tableView.editing, animated: true) @IBAction func editItemAction(sender: AnyObject) { tableView.editing = !tableView.editing } 效果图没有动画效果
tableView.editing = !tableView.editing有动画效果
tableView.setEditing(!tableView.editing, animated: true)cell 的默认编辑模式是 delete
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable. // 单行能够可选的设置编辑 1. 设置 tableView 的 editing 属性 2. 实现这个方法 // tableView 的某一行能够进行编辑模式 // 这个方法不实现,默认是每一行都进入编辑模式 optional public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool @IBAction func editItemAction(sender: AnyObject) { tableView.setEditing(!tableView.editing, animated: true) } // 这是一个数据源方法 // 设置 tableView 那一行进入编辑模式 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 双数 row 行进入编辑模式 if indexPath.row % 2 == 0 { return false } return true }
效果:
上部分只是编辑样式的展示
效果:
先进入了编辑模式,查看了每个 cell 的编辑模式的样式。(cell 的编辑模式的设置看上面的代码)在非编辑模式下,只有 cell 的编辑模式是 delete 的,才可以进行左侧滑。
关于 cell 侧滑功能的实现可以先查看这段代码, 后续后详细说明!
** 事件的回调处理 ** 实例代码
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { switch editingStyle { case .Delete: print("Delete") // 移除模型数据(不移除就会报错) localData.removeAtIndex(indexPath.row) // 删除某一行 cell tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .Insert: print("Insert") let str = "new" + localData[indexPath.row] // 添加模型数据 (不插入就会报错) localData.insert(str, atIndex: indexPath.row) // 这一步只会刷新插入的哪一行 tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .None: print("None") // None 样式 是给 cell 的移动准备的,这里永远也不会打印(移动的时候并不需要插入和删除) } } /*! 设置某一行的编辑样式 */ func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { print(#function) let number = indexPath.row % 3 switch number { case 0: return UITableViewCellEditingStyle.Delete case 1: return UITableViewCellEditingStyle.Insert default: // None 样式 是给 cell 的移动准备的 return UITableViewCellEditingStyle.None } }
回调效果:
进入到编辑模式后,会默认的调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle, 刷新每一行的 cell 编辑样式。点击左边的删除按钮,cell 会出现侧滑,显示一个 delete ,只有点击了 delete 之后才可以进行删除。 删除一个 cell 后,会再一次调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle方法,刷新每一个 cell 编辑样式 。(方法调用的个数变少了)点击添加按钮,cell 不会出现侧滑, 直接调用回调方法。会再一次调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 方法,刷新每一个 cell 编辑样式 。(cell 个数增加了)当 cell 的编辑样式是 None 的时候, 点击是没有任何效果的。注意点: 由于进行 delete 和 Insert 操作的回调 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 方法。 所以, cell 编辑模式需要用一个 数组来记录。来保证, delete 和 Insert 操作之后,和之前 cell 的编辑样式是对应的。
// 定义一个 空的数组 var cellEditingStyle: [Int] = [] // 设置默认值 for index in 0 ..< localData.count { cellEditingStyle.append(index) } func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { switch editingStyle { case .Delete: print("Delete") localData.removeAtIndex(indexPath.row) // 编辑模式数据删除 cellEditingStyle.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .Insert: print("Insert") localData.insert("new" + localData[indexPath.row], atIndex: indexPath.row) // 编辑模式数据添加 (设置为 删除) cellEditingStyle.insert(0, atIndex: indexPath.row) tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) case .None: print("None") // None 样式 是给 cell 的移动准备的,这里永远也不会打印 } } func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { print(#function) // 获取对应的数据进行设置 let number = cellEditingStyle[indexPath.row] % 3 switch number { case 0: return UITableViewCellEditingStyle.Delete case 1: return UITableViewCellEditingStyle.Insert default: return UITableViewCellEditingStyle.None } }
使用这种方式
编辑模式的数据可以和 cell 对应的模型数据绑定。一种 MVC 的思想
编辑模式中的选中操作用到的 API:
// 允许在编辑模式下进行单选 // 默认为 No public var allowsSelectionDuringEditing: Bool // default is NO. Controls whether rows can be selected when in editing mode // 允许在编辑模式进行多选 // 默认为 No public var allowsMultipleSelectionDuringEditing: Bool // default is NO. Controls whether multiple rows can be selected simultaneously in editing mode // 当前选中的索引的获取 // 获取当前选中单行的索引 public var indexPathForSelectedRow: NSIndexPath? { get } // returns nil or index path representing section and row of selection. // 获取当前选中多行的索引 public var indexPathsForSelectedRows: [NSIndexPath]? { get } // returns nil or a set of index paths representing the sections and rows of the selection.
代码演示:
// 进入编辑模式 tableView.editing = !tableView.editing // 编辑模式下单选 tableView.allowsSelectionDuringEditing = true // 编辑模式下多选 tableView.allowsMultipleSelectionDuringEditing = true
我使用的是 tableView.allowsMultipleSelectionDuringEditing = true 来实现单选和多选操作。tableView.allowsSelectionDuringEditing = true 效果后面介绍。这种效果也是我们在项目中最常见的
关键代码 @IBAction func editItemAction(sender: AnyObject) { // 非动画 // tableView.editing = !tableView.editing // tableView.allowsSelectionDuringEditing = !tableView.editing // 在编辑模式下多选 tableView.allowsMultipleSelectionDuringEditing = !tableView.editing // 动画 ( 建议使用这个 ) tableView.setEditing(!tableView.editing, animated: true) } /* 注释掉这个代码就可实现多选 */ // cell 将要选中的回调代理 // 在这个方法中主要进行的是取消上一次选中 func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { // 这个方法第一次调用的时候 indexPath 为 nil if let selectedRowIndexPath = tableView.indexPathForSelectedRow { // 去除上一次选中 tableView.deselectRowAtIndexPath(selectedRowIndexPath, animated: true) } return indexPath }
选中效果演示:
单选 多选操作当前选中的索引的获取
// 获取当前选中单行的索引 public var indexPathForSelectedRow: NSIndexPath? { get } // 获取当前选中多行的索引 public var indexPathsForSelectedRows: [NSIndexPath]? { get }
最简单的获取选中 cell 的方式就是下面的两个接口。使用这两个接口,我们就不需要另外的再去定义变量记录选中的 cell 。
tableView.allowsSelectionDuringEditing = true 的特别说明: 这个 tableView.allowsSelectionDuringEditing 设置效果是有点让人疑惑的。在看到多选的效果后,我一直以为 编辑模式下,单选 的效果 和 多选的效果类似,也应该有个 圈圈 事实证明我是错的!单选和多选的效果:普通模式下的不能选择,单选和多选:
// 这个属性,默认是 true 的,设置为 false 后,不能进行 cell 的选中操作。 // 同时也禁止了 代理方法选中的回调 tableView.allowsSelection = false点击 cell 没人任何效果!
tableView.allowsSelection = false tableView.allowsSelection = true tableView.allowsSelection = true // 多选为 true 后,单选肯定也为 true tableView.allowsMultipleSelection = true编辑模式下的单选:
tableView.editing = true // 编辑模式下,cell 默认是不能进行选中操作的 tableView.allowsSelectionDuringEditing = false
在编辑模式下,默认 cell 默认是不能响应点击事件的。并且,control view 还是会根据 cell 编辑模式的进行显示(我们看到的加号 ,减号,空白)。
tableView.allowsMultipleSelection = false tableView.editing = true tableView.allowsSelectionDuringEditing = true
单选是没有 圈圈 效果的,就是单纯的 cell 高亮。并且,control view 还是会根据 cell 编辑模式的进行显示(我们看到的加号 ,减号,空白)。
tableView.allowsSelectionDuringEditing = true tableView.editing = true tableView.allowsMultipleSelectionDuringEditing = true
多选模式下,会修改 control view 的显示,将 加号,减号,空白替换为 圈圈
默认情况下tableView 中的 cell 是不能进行移动操作, 只有在编辑模式下,tableView 的 cell 可以进行移动操作。
简单的显示 cell 移动的附加视图
这只是简单的效果显示
// Data manipulation - reorder / moving support optional public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) // 进入编辑模式 tableView.editing = !tableView.editing // cell 的移动和排序操作 ( 方法的简单实现) func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { } // 消除不必要的影响 /*! 设置某一行的编辑样式 */ func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle { // 获取 cell 对应的编辑模式的缓存数据 let number = cellEditingStyle[indexPath.row] % 3 switch number { // 注释这里,主要是为了消除,其他功能的影响。 // case 0: // print("0") // return UITableViewCellEditingStyle.Delete // case 1: // print("1") // return UITableViewCellEditingStyle.Insert default: print("2") // 这一个模式是用来排序移动准备用的 return UITableViewCellEditingStyle.None } }
效果:
效果:
效果图
效果图
当只实行单独设置索引的方法,点击索引会默认的滚动到索引对应顺序的组。
// 索引设置 func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { return ["A","B","C","D","E", "F", "G"] } // 告诉表部分对应部分标题/索引(当点击索引的时候回调用这个方法) /* 实现这个方法,点击索引的只会滚动一次,滚动后执行的是索引的回调 */ func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { print(title , index) return 3 } 链接:https://www.jianshu.com/p/aaf2c88c58f0