读了官方的这篇文章 Inserting and Deleting Rows and Sections 写一个笔记
------
Table View 的编辑模式如下图所示,左边的按钮是editing control, 右边的recording control
通常是用户点击 eding control 之后,Table View才会进入编辑模式,执行插入或者删除,但这并不是绝对。也就是说,没有进入编辑模式,也可以执行插入或者编辑操作。
1. 编辑模式下的插入删除
Table View 在接收到 setEditing:animated:
函数的信息之后进入编辑模式
通常,这个函数都是由用户点击导航栏上的编辑按钮(一般都是这么设计摆放这个按钮的)所触发。
在编辑模式下,每行都由 delegate 分配给左边 editing control 和右边 recording control
注意⚠️: 如果是UIViewController 管理的Table View,它会在编辑按钮被点击的时候自动接收到
setEditing:animated:
函数的信息,并在Table View 的相应函数被调用之前,就更新按钮状态或者响应其它任务。
在Table View 接收到信息之后,它会给每个可视行的 UITableViewCell 对象发送同样的信息,然后发送一连串的信息给 data source 和 Delegate
在再次发送消息给对应可是行的单元格时,消息序列如下所示:
- Table View 调用
tableView:canEditRowAtIndexPath:
方法(如果这个方法有在datasource中实现的话)。 这个方法决定了Table View对应的单元能不能被编辑,优先级高于editingStyle
属性,也就是说,无论cell’s editingStyle prop
设置的是什么,都是以有实现的这个方法为准。 - Table View
tableView:editingStyleForRowAtIndexPath:
方法(如果这个方法有在delegate中实现的话)。这个方法决定了editing control样式和功能。这时,Table View 已经完全进入编辑模式。 显示了每一个被允许编辑行的插入删除模式。 - 用户点击editing control (插入或者删除按钮,开篇图片中的左半部分)。这一步也就是点击删除按钮时发送的确认消息。也就是通常出现在右半部分那个按钮。
- Table view 发送
tableView:commitEditingStyle:forRowAtIndexPath:
消息给 data source。 虽然这个方法在data source中是可选的,但是如果要进行插入删除操作的话一定要实现。这个方法做两家事情:
- 发送
deleteRowsAtIndexPaths:withRowAnimation:
或者insertRowsAtIndexPaths:withRowAnimation:
指示Table view 刷新显示 。 - 通过增删数据模型数组同步更新数据模型。
当用户通过滑动来删除的时候,调用顺序是跟上述有些许不同的。当用户滑动的时候,Table View首先检测tableView:commitEditingStyle:forRowAtIndexPath:
是否有实现。如果实现了,Table View将发送setEditing:animated:
给自己然后进入编辑模式。在这个“滑动删除”模式中,Table View不会显示editing control和 reordering control。因为这是一个用户驱动事件,并且将消息包在tableView:willBeginEditingRowAtIndexPath:
和tableView:didEndEditingRowAtIndexPath:
中。通过实现这两个方法,delegate将会正确显示Table View 。
注意⚠️: _Data source _不应该从
tableView:commitEditingStyle:forRowAtIndexPath:
的实现(OC中@implementation
)部分的内部调用setEditing:animated:
。如果出于某种原因必须这么做的话,需要用performSelector:withObject:afterDelay:
函数设置延迟调用。
虽然可以使用insertion control 作为触发器来插入新的行,但是另外可供选择的方法是在导航栏上添加一个“添加”按钮。点击按钮发送action
信息给view controller
,然后用一个modal view
覆盖table view
来填写新项的具体内容,再把数据添加到数据模型数组中,最后调用tableView.reload()
刷新table view
。