我有一个从核心数据中获取数据的TableView。
保存数据后,它们将作为第一行插入。
这是我用来保存数据的代码(我没有使用fetch控制器,因为我没有获取任何数据,只是加载它们,这是因为我加载的日期来自一个很多关系)
swimToConnect.addToMaterialsLocal(materialLocal)
ad.saveContext()
// Adding the new row to update the tableView
let MyMaterialsVC = self.presentingViewController?.presentingViewController?.presentingViewController as! MyMaterialsVC
MyMaterialsVC.myMaterials.insert(materialLocal, at: 0)
MyMaterialsVC.tableView.insertRows(at: [NSIndexPath(row: 0, section: 0) as IndexPath], with: .none)
MyMaterialsVC.dismiss(animated: true, completion: nil)
}
所以我想知道是否有办法插入按日期排序的行。 我按照日期订购了它们:
var swim: SwimminPool! {
didSet {
myMaterials = (swim.materialsLocal?.allObjects as! [MaterialLocal]).sorted(by: {$0.createdAtLocal! > $1.createdAtLocal!})
}
}
创建时间是用户添加日期选择器的日期。 当我保存新数据显然它们显示在第一行,但如果我关闭控制器然后重新进入,那么数据将根据日期顺序显示。
有没有办法在我保存数据后立即以正确的顺序订购数据?
谢谢。
答案 0 :(得分:0)
将此更改为以下
swimToConnect.addToMaterialsLocal(materialLocal)
ad.saveContext()
// Adding the new row to update the tableView
let MyMaterialsVC = self.presentingViewController?.presentingViewController?.presentingViewController as! MyMaterialsVC
MyMaterialsVC.myMaterials.insert(materialLocal, at: 0)
MyMaterialsVC.myMaterials = (swim.materialsLocal?.allObjects as! [MaterialLocal]).sorted(by: {$0.createdAtLocal! > $1.createdAtLocal!})
MyMaterialsVC.tableView.reloadData()
MyMaterialsVC.dismiss(animated: true, completion: nil)
}
答案 1 :(得分:0)
此问题的最佳解决方法是使用NSFetchedResultsController
。它负责有效地插入和删除项目,并使用NSPredicate
对它们进行排序。
您可以在Xcode中创建一个主详细信息应用程序模板并选中核心数据框,然后Xcode使用FetchedResultsController创建一个示例应用程序,在那里您可以看到它是如何工作的。
答案 2 :(得分:0)
这是RandomAccessCollection
的扩展,它以非常有效的方式返回新项目的排序集合中的插入索引。好处是您不需要重新加载整个表视图。
extension RandomAccessCollection {
func insertionIndex(for predicate: (Element) -> Bool) -> Index {
var slice : SubSequence = self[...]
while !slice.isEmpty {
let middle = slice.index(slice.startIndex, offsetBy: slice.count / 2)
if predicate(slice[middle]) {
slice = slice[index(after: middle)...]
} else {
slice = slice[..<middle]
}
}
return slice.startIndex
}
}
你可以使用它:
let insertionIndex = MyMaterialsVC.myMaterials.insertionIndex(for: { $0.createdAtLocal! < materialLocal.createdAtLocal!})
MyMaterialsVC.myMaterials.insert(materialLocal, at: insertionIndex)
MyMaterialsVC.tableView.insertRows(at: [IndexPath(row: insertionIndex, section: 0)], with: .none)
MyMaterialsVC.dismiss(animated: true, completion: nil)