Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSFetchedResultsController未正确更新tableView_Ios_Swift_Uitableview_Core Data - Fatal编程技术网

Ios NSFetchedResultsController未正确更新tableView

Ios NSFetchedResultsController未正确更新tableView,ios,swift,uitableview,core-data,Ios,Swift,Uitableview,Core Data,我在viewDidLoad中获取一些项(NSManagedObject),并使用NSFetchedResultsController委托更新swift ios中的tableView单元格(来自Apple文档的用于插入、删除等的委托),问题是,当我向相同ManagedObject类型的核心数据添加项时,我希望该表使用新项更新,但是,最后一项将从tableview中删除,而新项不会添加。我只在再次加载屏幕时看到新项目。。。有什么不对劲吗? 这是我的fetchedResultsController:

我在viewDidLoad中获取一些项(NSManagedObject),并使用NSFetchedResultsController委托更新swift ios中的tableView单元格(来自Apple文档的用于插入、删除等的委托),问题是,当我向相同ManagedObject类型的核心数据添加项时,我希望该表使用新项更新,但是,最后一项将从tableview中删除,而新项不会添加。我只在再次加载屏幕时看到新项目。。。有什么不对劲吗? 这是我的fetchedResultsController:

lazy var fetchedResultsController: NSFetchedResultsController<Message> = {
    let context = CoreDataManager.shared.persistentContainer.viewContext
    let request: NSFetchRequest<Message> = Message.fetchRequest()

    request.sortDescriptors = [
        NSSortDescriptor(key: "createdAt", ascending: true)
    ]
    request.fetchLimit = 40

    let frc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

    // fetch only messages with that recipient id of the chat.
    let recipientId = "\(chat!.recipientId)"
    request.predicate = NSPredicate(format: "recipientId == %@", recipientId)

    return frc
}()
聊天管理对象有一个属性lastMessage,它是Message类型(也是一个托管对象),我将新创建的消息设置为聊天的最后一条消息。问题可能就在那里。 下面是代理代码:

// MARK: - NSFetchedResultsController Delegates

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
    case .delete:
        tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
    case .move:
        break
    case .update:
        break
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .right)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .fade)
    case .update:
        tableView.reloadRows(at: [indexPath!], with: .fade)
    case .move:
        tableView.moveRow(at: indexPath!, to: newIndexPath!)
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}
//标记:-NSFetchedResultsController委托
func controllerWillChangeContent(\ucontroller:NSFetchedResultsController){
tableView.beginUpdate()
}
func控制器(控制器:NSFetchedResultsController,didChange sectionInfo:NSFetchedResultsSectionInfo,atSectionIndex sectionIndex:Int,类型:NSFetchedResultsChangeType){
开关类型{
案例.插入:
tableView.insertSections(IndexSet(整数:sectionIndex),带:.fade)
案例.删除:
tableView.deleteSections(IndexSet(整数:sectionIndex),带:.fade)
案件.动议:
打破
案例。更新:
打破
}
}
func控制器(controller:NSFetchedResultsController,didChange anObject:Any,在indexPath:indexPath?处,对于类型:NSFetchedResultsChangeType,newIndexPath:indexPath?){
开关类型{
案例.插入:
tableView.insertRows(位于:[newIndexPath!],带:。右侧)
案例.删除:
tableView.deleteRows(位于:[indexPath!],带:.fade)
案例。更新:
tableView.reloadRows(位于:[indexPath!],带:.fade)
案件.动议:
tableView.moveRow(at:indexPath!,to:newIndexPath!)
}
}
func controllerDidChangeContent(\控制器:NSFetchedResultsController){
tableView.endUpdates()
}

请注意,您对移动行(.move)的处理只移动一行,您应该实现它以移动多行。不确定这是否解决了问题,这取决于数据的排序方式

下面是我如何实现我的.move

case .move:
    if let indexPath = indexPath {
        tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: .effectFade)
    }
    if let newIndexPath = newIndexPath {
        tableView.insertRows(at: IndexSet.init(integer: newIndexPath.item), withAnimation: .effectFade)
    }

... 我正在使用NSFetchedResultsController委托。你在哪里设置代理?代理在viewDidLoad中设置,我也在那里进行抓取。也许你也应该向我们显示代理代码。我已经添加了代理代码。我的排序是基于日期的。此外,排序是否会触发移动?因为我只是像我说的那样插入新项目,我不确定它是否解决了您的问题,也许您可以尝试一下,但它仍然是一个改进,因为它处理多行就像您的其他开关情况一样。如果没有帮助,我会删除这个答案。
case .move:
    if let indexPath = indexPath {
        tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: .effectFade)
    }
    if let newIndexPath = newIndexPath {
        tableView.insertRows(at: IndexSet.init(integer: newIndexPath.item), withAnimation: .effectFade)
    }