经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
UITableView编辑模式大全解
来源:cnblogs  作者:鸿鹄当高远  时间:2019/1/14 9:34:35  对本文有异议

 

1、UITableView 的编辑模式

进入编辑模式
代码体现

  1. // 设置 editing 属性
  2. tableView?.editing = true
  3.  
  4. // 这个设置的时候是有动画效果的
  5. tableView.setEditing(true, animated: true)
  6. // 我一般喜欢的设置方式 (写在 btn 或者 item 的监听方法里面)
  7. // 实现编辑模式和非编辑模式的切换
  8. tableView.editing = !tableView.editing
  9. tableView.setEditing(!tableView.editing, animated: true)
  10. @IBAction func editItemAction(sender: AnyObject) {
  11. tableView.editing = !tableView.editing
  12. }

  1. 效果图

没有动画效果


 
tableView.editing = !tableView.editing

有动画效果


 
tableView.setEditing(!tableView.editing, animated: true)

2、 设置某一行能够进行编辑

cell 的默认编辑模式是 delete

  1. // Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
  2. // 单行能够可选的设置编辑
  3. 1. 设置 tableView editing 属性
  4. 2. 实现这个方法
  5. // tableView 的某一行能够进行编辑模式
  6. // 这个方法不实现,默认是每一行都进入编辑模式
  7. optional public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
  8. @IBAction func editItemAction(sender: AnyObject) {
  9. tableView.setEditing(!tableView.editing, animated: true)
  10. }
  11. // 这是一个数据源方法
  12. // 设置 tableView 那一行进入编辑模式
  13. func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
  14. // 双数 row 行进入编辑模式
  15. if indexPath.row % 2 == 0 {
  16. return false
  17. }
  18. return true
  19. }

 

 
 

3、 设置某一行编辑模式的样式

  1. cell 编辑模式枚举
  2. public enum UITableViewCellEditingStyle : Int {
  3. case None // 正常模式 (这一个主要用于 cell 的移动)
  4. case Delete // 删除模式
  5. case Insert // 插入模式
  6. }
  7. cell 编辑模式设置
  8. // Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
  9. // 允许用户通过实行这个方法来自定义 cell 的编辑样式, 如果没有实现这个方法, 所有的 cell 的默认编辑样式为 UITableViewCellEditingStyleDelete . 只有 editing 属性设置为 true 的时候才可以看到效果
  10. optional public func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
  11. 代码
  12. /*!
  13. 设置某一行的编辑样式
  14. */
  15. func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  16. let number = indexPath.row % 3
  17. switch number {
  18. case 0:
  19. print("0")
  20. return UITableViewCellEditingStyle.Delete
  21. case 1:
  22. print("1")
  23. return UITableViewCellEditingStyle.Insert
  24. default:
  25. print("2")
  26. return UITableViewCellEditingStyle.None
  27. }
  28. }

 

效果:

 
 

上部分只是编辑样式的展示

4、 编辑模式的事件回调

  1. @available(iOS 2.0, *)
  2. // 编辑样式 add 和 delete 附加视图点击的回调
  3. optional public func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
  4. 默认实现编辑事件回调方法:
  5. func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
  6. // 没有添加任何的功能代码
  7. }
  8. 实现这个方法后,在非编辑模式下,左滑动 cell 会显示一个 delete 按钮。

 

效果:

 
 

先进入了编辑模式,查看了每个 cell 的编辑模式的样式。(cell 的编辑模式的设置看上面的代码)
在非编辑模式下,只有 cell 的编辑模式是 delete 的,才可以进行左侧滑。

关于 cell 侧滑功能的实现可以先查看这段代码, 后续后详细说明!



** 事件的回调处理 **
实例代码

  1. func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
  2. switch editingStyle {
  3. case .Delete:
  4. print("Delete")
  5. // 移除模型数据(不移除就会报错)
  6. localData.removeAtIndex(indexPath.row)
  7. // 删除某一行 cell
  8. tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  9. case .Insert:
  10. print("Insert")
  11. let str = "new" + localData[indexPath.row]
  12. // 添加模型数据 (不插入就会报错)
  13. localData.insert(str, atIndex: indexPath.row)
  14. // 这一步只会刷新插入的哪一行
  15. tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  16. case .None:
  17. print("None") // None 样式 是给 cell 的移动准备的,这里永远也不会打印(移动的时候并不需要插入和删除)
  18. }
  19. }
  20. /*!
  21. 设置某一行的编辑样式
  22. */
  23. func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  24. print(#function)
  25. let number = indexPath.row % 3
  26. switch number {
  27. case 0:
  28. return UITableViewCellEditingStyle.Delete
  29. case 1:
  30. return UITableViewCellEditingStyle.Insert
  31. default:
  32. // None 样式 是给 cell 的移动准备的
  33. return UITableViewCellEditingStyle.None
  34. }
  35. }

 

回调效果:

 
 
  1. 进入到编辑模式后,会默认的调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle, 刷新每一行的 cell 编辑样式。
  2. 点击左边的删除按钮,cell 会出现侧滑,显示一个 delete ,只有点击了 delete 之后才可以进行删除。 删除一个 cell 后,会再一次调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle方法,刷新每一个 cell 编辑样式 。(方法调用的个数变少了)
  3. 点击添加按钮,cell 不会出现侧滑, 直接调用回调方法。会再一次调用 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 方法,刷新每一个 cell 编辑样式 。(cell 个数增加了)
  4. 当 cell 的编辑样式是 None 的时候, 点击是没有任何效果的。

注意点:
由于进行 delete 和 Insert 操作的回调 func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 方法。
所以, cell 编辑模式需要用一个 数组来记录。来保证, delete 和 Insert 操作之后,和之前 cell 的编辑样式是对应的。

  1. // 定义一个 空的数组
  2. var cellEditingStyle: [Int] = []
  3. // 设置默认值
  4. for index in 0 ..< localData.count {
  5. cellEditingStyle.append(index)
  6. }
  7. func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
  8. switch editingStyle {
  9. case .Delete:
  10. print("Delete")
  11. localData.removeAtIndex(indexPath.row)
  12. // 编辑模式数据删除
  13. cellEditingStyle.removeAtIndex(indexPath.row)
  14. tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  15. case .Insert:
  16. print("Insert")
  17. localData.insert("new" + localData[indexPath.row], atIndex: indexPath.row)
  18. // 编辑模式数据添加 (设置为 删除)
  19. cellEditingStyle.insert(0, atIndex: indexPath.row)
  20. tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  21. case .None:
  22. print("None") // None 样式 是给 cell 的移动准备的,这里永远也不会打印
  23. }
  24. }
  25. func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  26. print(#function)
  27. // 获取对应的数据进行设置
  28. let number = cellEditingStyle[indexPath.row] % 3
  29. switch number {
  30. case 0:
  31. return UITableViewCellEditingStyle.Delete
  32. case 1:
  33. return UITableViewCellEditingStyle.Insert
  34. default:
  35. return UITableViewCellEditingStyle.None
  36. }
  37. }

 

使用这种方式

 
 

编辑模式的数据可以和 cell 对应的模型数据绑定。一种 MVC 的思想

5、 编辑模式中的选中操作

编辑模式中的选中操作用到的 API:

  1. // 允许在编辑模式下进行单选
  2. // 默认为 No
  3. public var allowsSelectionDuringEditing: Bool // default is NO. Controls whether rows can be selected when in editing mode
  4. // 允许在编辑模式进行多选
  5. // 默认为 No
  6. public var allowsMultipleSelectionDuringEditing: Bool // default is NO. Controls whether multiple rows can be selected simultaneously in editing mode
  7. // 当前选中的索引的获取
  8. // 获取当前选中单行的索引
  9. public var indexPathForSelectedRow: NSIndexPath? { get } // returns nil or index path representing section and row of selection.
  10. // 获取当前选中多行的索引
  11. public var indexPathsForSelectedRows: [NSIndexPath]? { get } // returns nil or a set of index paths representing the sections and rows of the selection.

 

代码演示:

  1. // 进入编辑模式
  2. tableView.editing = !tableView.editing
  3. // 编辑模式下单选
  4. tableView.allowsSelectionDuringEditing = true
  5. // 编辑模式下多选
  6. tableView.allowsMultipleSelectionDuringEditing = true

 

我使用的是 tableView.allowsMultipleSelectionDuringEditing = true 来实现单选和多选操作。
tableView.allowsSelectionDuringEditing = true 效果后面介绍。
这种效果也是我们在项目中最常见的

  1. 关键代码
  1. @IBAction func editItemAction(sender: AnyObject) {
  2. // 非动画
  3. // tableView.editing = !tableView.editing
  4. // tableView.allowsSelectionDuringEditing = !tableView.editing
  5. // 在编辑模式下多选
  6. tableView.allowsMultipleSelectionDuringEditing = !tableView.editing
  7. // 动画 ( 建议使用这个 )
  8. tableView.setEditing(!tableView.editing, animated: true)
  9. }
  10. /* 注释掉这个代码就可实现多选 */
  11. // cell 将要选中的回调代理
  12. // 在这个方法中主要进行的是取消上一次选中
  13. func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
  14. // 这个方法第一次调用的时候 indexPath 为 nil
  15. if let selectedRowIndexPath = tableView.indexPathForSelectedRow {
  16. // 去除上一次选中
  17. tableView.deselectRowAtIndexPath(selectedRowIndexPath, animated: true)
  18. }
  19. return indexPath
  20. }

 

选中效果演示:

 
单选
 
多选操作

当前选中的索引的获取

  1. // 获取当前选中单行的索引
  2. public var indexPathForSelectedRow: NSIndexPath? { get }
  3. // 获取当前选中多行的索引
  4. public var indexPathsForSelectedRows: [NSIndexPath]? { get }

 


最简单的获取选中 cell 的方式就是下面的两个接口。使用这两个接口,我们就不需要另外的再去定义变量记录选中的 cell 。



tableView.allowsSelectionDuringEditing = true 的特别说明:


这个 tableView.allowsSelectionDuringEditing 设置效果是有点让人疑惑的。在看到多选的效果后,我一直以为 编辑模式下,单选 的效果 和 多选的效果类似,也应该有个 圈圈 事实证明我是错的!
单选和多选的效果:
普通模式下的不能选择,单选和多选:

  1. // 这个属性,默认是 true 的,设置为 false 后,不能进行 cell 的选中操作。
  2. // 同时也禁止了 代理方法选中的回调
  3. tableView.allowsSelection = false

点击 cell 没人任何效果!


 
tableView.allowsSelection = false
  1. tableView.allowsSelection = true
 
tableView.allowsSelection = true
  1. // 多选为 true 后,单选肯定也为 true
  2. tableView.allowsMultipleSelection = true
 
 

编辑模式下的单选:

  1. tableView.editing = true
  2. // 编辑模式下,cell 默认是不能进行选中操作的
  3. tableView.allowsSelectionDuringEditing = false

 

在编辑模式下,默认 cell 默认是不能响应点击事件的。并且,control view 还是会根据 cell 编辑模式的进行显示(我们看到的加号 ,减号,空白)。


 
tableView.allowsMultipleSelection = false
  1. tableView.editing = true
  2. tableView.allowsSelectionDuringEditing = true

 

单选是没有 圈圈 效果的,就是单纯的 cell 高亮。并且,control view 还是会根据 cell 编辑模式的进行显示(我们看到的加号 ,减号,空白)。

 
tableView.allowsSelectionDuringEditing = true
  1. tableView.editing = true
  2. tableView.allowsMultipleSelectionDuringEditing = true

 

多选模式下,会修改 control view 的显示,将 加号,减号,空白替换为 圈圈

 
 

 

6、 编辑模式中 cell 的 Move (移动操作)

默认情况下tableView 中的 cell 是不能进行移动操作, 只有在编辑模式下,tableView 的 cell 可以进行移动操作。

简单的显示 cell 移动的附加视图

这只是简单的效果显示

  1. // Data manipulation - reorder / moving support
  2. optional public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
  3. // 进入编辑模式
  4. tableView.editing = !tableView.editing
  5. // cell 的移动和排序操作 ( 方法的简单实现)
  6. func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
  7. }
  8. // 消除不必要的影响
  9. /*!
  10. 设置某一行的编辑样式
  11. */
  12. func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
  13. // 获取 cell 对应的编辑模式的缓存数据
  14. let number = cellEditingStyle[indexPath.row] % 3
  15. switch number {
  16. // 注释这里,主要是为了消除,其他功能的影响。
  17. // case 0:
  18. // print("0")
  19. // return UITableViewCellEditingStyle.Delete
  20. // case 1:
  21. // print("1")
  22. // return UITableViewCellEditingStyle.Insert
  23. default:
  24. print("2")
  25. // 这一个模式是用来排序移动准备用的
  26. return UITableViewCellEditingStyle.None
  27. }
  28. }

 

效果:


 
 

7、 编辑模式中指定某一行 cell 可以 Move

  1. // 指定哪一个 cell 能够移动
  2. func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
  3. // 单数 row 行进入可移动模式
  4. if indexPath.row % 2 == 0 {
  5. return false
  6. }
  7. return true
  8. }

 

效果:

 
 

3、tableView 的移动和排序

  1. // Moving/reordering
  2. // Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
  3. // 允许某一行的排序的附加视图显示,只用在数据源 实现了 -tableView:moveRowAtIndexPath:toIndexPath: 方法的时候 这个方法才有效
  4. @available(iOS 2.0, *)
  5. optional public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool
  6. 传说中支持移动和排序的方法
  7. // Data manipulation - reorder / moving support
  8. @available(iOS 2.0, *)
  9. optional public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
  10. 代码体现
  11. // cell 的移动和排序操作
  12. func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
  13. }
  14. // 指定哪一个 cell 能够移动
  15. func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
  16. // 单数 row 行进入可移动模式
  17. if indexPath.row % 2 == 0 {
  18. return false
  19. }
  20. return true
  21. }

 

效果图


 
 

4、tableView 索引设置

  1. // Index
  2. @available(iOS 2.0, *)
  3. // 通过实行这个方法,返回一个 string 的数组就可以设置索引
  4. optional public func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? // return list of section titles to display in section index view (e.g. "ABCD...Z#")
  5. @available(iOS 2.0, *)
  6. // 索引选中的回调
  7. optional public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1))
  8. 单独设置索引
  9. // 索引设置
  10. func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
  11. return ["A","B","C","D","E", "F", "G"]
  12. }

 

效果图

 
 

当只实行单独设置索引的方法,点击索引会默认的滚动到索引对应顺序的组。

  1. // 索引设置
  2. func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
  3. return ["A","B","C","D","E", "F", "G"]
  4. }
  5. // 告诉表部分对应部分标题/索引(当点击索引的时候回调用这个方法)
  6. /*
  7. 实现这个方法,点击索引的只会滚动一次,滚动后执行的是索引的回调
  8. */
  9. func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
  10. print(title , index)
  11. return 3
  12. }
链接:https://www.jianshu.com/p/aaf2c88c58f0

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号