2016-08-19 88 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() 
} 
相關問題