2016-08-19 73 views
1

在我的聊天应用程序中,“lastMessage”是实体Friend和消息之间的关系。每个Friend实体都有一组消息并且只有一个lastMessage。因此,如果我发送一条消息进行计费,则账单的“lastMessage”将更新为较新的时间戳。也就是说,fetchedResultsController的获取对象包含每个朋友的lastMessage.timestamp的数组。我遇到的问题是与UITableView。如果我在聊天控制器中向朋友发送一条消息,并按回来,同时简单地在DidChangeContent内部有“messageTable.reloadData”,我发送消息的朋友,他的lastMessage更新为最新的时间戳,并被排序为fetchedResultsController中的第一个条目,让他在桌面上的第一个位置。但是,因为我希望通过在didChangeObject中使用self.messagesTable.reloadRowsAtIndexPaths([indexPath!],withRowAnimation:UITableViewRowAnimation.None)添加动画,所以没有任何内容可以正确重新加载。我尝试将它放入.Insert,.Update和.Move一次全部移动。我很新的将NSFetchedResultsController同步到一个tableView。所以我不知道如何通过NSFetchedResultsController正常实现重新加载表。将NSFetchedResultsController与UITableView同步

@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() 


    } 

回答

1

相反的reloadRowsAtIndexPaths,使用insertRowsAtIndexPathsdeleteRowsAtIndexPaths方法。此外,在controllerWillChangeContent方法中使用beginUpdates,在controllerDidChangeContent中使用endUpdates。例如:

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() 
} 
相关问题