我正在通过编写一个表应用程序视图来学习Swift,该视图在启动时列出了核心数据表(实体)的内容。然后,用户可以对表视图中的行进行重新排序。
我需要能够保存新排序的行,以便它们替换先前的数据库表,因此,当用户再次启动应用程序时,将显示新订单。
长按并激活即可激活编辑(重新排序)功能
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
self.projectTableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)
}
再长按一次即可停用编辑功能:
// Called when long press occurred
@objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer){
if gestureRecognizer.state == .ended {
let touchPoint = gestureRecognizer.location(in: self.projectTableView)
if let indexPath = projectTableView.indexPathForRow(at: touchPoint) {
if self.projectTableView.isEditing == true {
self.projectTableView.isEditing = false
db.updateAll() //this is a stub
} else {
self.projectTableView.isEditing = true
}
}
}
}
上面的“ handleLongPress”中对db.updateAll()的调用只是一个空白,我不知道如何更新数据库。有没有一种方法可以将新序列中tableView的内容读入数组,然后替换db中的表?感觉有点“蛮力”,但看不到其他解决方案。
答案 0 :(得分:2)
好的,您可以通过几种方式实现这一目标:
1-使用NSFetchedResultsController
,您可以在此处自动将对核心数据持久性存储所做的更改与表视图同步,
步骤如下:
NSFetchedResultsControllerDelegate
NSFetchedResultsController
的实例NSFetchRequest
,使用请求调用NSFetchedResultsController
初始化程序,然后将其分配给您在performFetch
方法现在您可以实现委托,在这里您需要didChange
,类似这样:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
didChange anObject: Any,
at indexPath: IndexPath?,
for type: NSFetchedResultsChangeType,
newIndexPath: IndexPath?) {
switch type {
/*
....
*/
case .move:
if let deleteIndexPath = indexPath {
self.tableView.deleteRows(at: [deleteIndexPath], with: .fade)
}
if let insertIndexPath = newIndexPath {
self.tableView.insertRows(at: [insertIndexPath], with: .fade)
}
}
}
2-第二种选择,我个人更喜欢它而不是NSFetchedResultscontroller
您可以在模型(核心数据模型)中添加属性。可以是Int,例如“ orderNum”。 因此,当您提取请求时,您可以使用此属性来订购结果。
因此,如果重新排列了表格视图单元格,则在实现moveItem方法之后,您可以为所有对象更新该属性(在它们上循环),并且它们将与显示的一样。
尝试立即保存您的托管对象上下文,
下次要提取请求时,可以使用排序描述符对“ orderNum”进行排序。
答案 1 :(得分:1)
也许在调用moveRowAt时更新数据源(通过删除并重新插入项目)会更好?
类似这样:
// assuming your data source is an array of names
var data = ["Jon", "Arya", "Tyrion", "Sansa", "Winterfell"]
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
self.projectTableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)
let item = self.data.remove(at: sourceIndexPath.row)
if sourceIndexPath.row > destinationIndexPath.row {
// "Sansa" was moved to be between "Jon" and "Arya"
self.data.insert(item, at: destinationIndexPath.row
} else {
// if the new destination comes after previous location i.e. "Sansa"
// was moved to the end of the list
self.data.insert(item, at: destinationIndexPath.row - 1
}
}