在我的聊天应用中," lastMessage"是朋友和消息实体之间的关系。每个Friend实体都有一组消息,只有一个lastMessage。因此,如果我向账单发送消息,请注明" lastMessage"将更新为更新的时间戳。也就是说,fetchedResultsController的获取对象包含每个朋友的lastMessage.timestamp的数组。我遇到的问题是UITableView。如果我在chatController中向朋友发送消息,然后按下" messageTable.reloadData"在我发信息的朋友DidChangeContent内部,他的lastMessage被更新为最新的时间戳,并被排序为fetchedResultsController中的第一个条目,将他移动到tableview的第一个位置。但是,由于我希望通过在didChangeObject中使用self.messagesTable.reloadRowsAtIndexPaths([indexPath!],withRowAnimation:UITableViewRowAnimation.None)来添加动画,所以没有任何内容正在正确地重新加载。我尝试将它插入.Insert,.Update和.Move一次。我非常擅长将NSFetchedResultsController同步到tableView。因此,我不确定如何通过NSFetchedResultsController正常实现重新加载表。
@IBOutlet weak var messagesTable: UITableView!
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Friend")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "lastMessage.timestamp", ascending: false)]
let predicate = NSPredicate(format: "lastMessage.timestamp != nil")
fetchRequest.predicate = predicate
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
if type == .Insert {
self.messagesTable.reloadRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
self.messagesTable.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
}
if type == .Update{
// self.collectionView?.cha([newIndexPath!])
print("h")
self.messagesTable.reloadRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
self.messagesTable.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
}
if type == .Move{
// self.collectionView?.cha([newIndexPath!])
print("h")
self.messagesTable.reloadRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
self.messagesTable.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.None)//reloadItemsAtIndexPaths([indexPath!])
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.messagesTable.beginUpdates()
}
答案 0 :(得分:1)
使用reloadRowsAtIndexPaths
和insertRowsAtIndexPaths
方法代替deleteRowsAtIndexPaths
。另外,在beginUpdates
方法中使用controllerWillChangeContent
,在endUpdates
中使用controllerDidChangeContent
。例如:
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.messagesTable.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.messagesTable.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.messagesTable.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
self.messagesTable.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
self.messagesTable.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
self.messagesTable.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Move:
self.messagesTable.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
self.messagesTable.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.messagesTable.endUpdates()
}