【问题标题】:How to use NSFetchedResultsController to update tableview content如何使用 NSFetchedResultsController 更新 tableview 内容
【发布时间】:2018-06-23 13:21:54
【问题描述】:

我正在更新 coredata 的某些部分,我希望 NSFetchedResultsController 自动重新加载包含所有动画的 tableview。我正在更改用于对 tableview 进行排序的 coredata 元素。我通过在单元格上向右滑动然后将特定的 tableviewcell 的 priorityNumber 更改为零来执行此操作,以便任务进入底部和其他一些事情。我希望表格重新加载但带有动画。现在我只是在做 tableView.reload() 它只是不能正常工作。

我想看到单元格移动到设备底部的动画。任何帮助将不胜感激!

代码如下: 我为 coreData 带来的变化:

func tableView(_ tableView: UITableView,
               leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
    let closeAction = UIContextualAction(style: .normal, title:  "✓", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in

        //???

        self.fetchedResultsController.object(at: indexPath).sTaskCompleted = !(self.fetchedResultsController.object(at: indexPath).sTaskCompleted)

        if ( self.fetchedResultsController.object(at: indexPath).sTaskCompleted)
        {
            print("Completed")
            //Change priority number to 0 after saving their current priority number in previousPN
            //Change priority circle color
            //Change background of the cell to something else




            self.fetchedResultsController.object(at: indexPath).sPreviousPN = self.fetchedResultsController.object(at: indexPath).sPriorityNumber
            self.fetchedResultsController.object(at: indexPath).sPriorityNumber = 0
            self.fetchedResultsController.object(at: indexPath).cellbackgroundColor = UIColor(red:0.93, green:0.91, blue:0.91, alpha:1.0)
            self.fetchedResultsController.object(at: indexPath).previousPriorityColor = self.fetchedResultsController.object(at: indexPath).sPriorityColor
            self.fetchedResultsController.object(at: indexPath).sPriorityColor = .clear

            var error: NSError?


            do {
                // Save The object

                try self.moContext.save()
                print("SAVED")
            } catch let error1 as NSError {
                error = error1
            }


            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                UIView.transition(with: tableView,
                                  duration: 0.15,
                                  options: .transitionCrossDissolve,
                                  animations: { self.tableView.reloadData() })
            })

        } else {
            print("InCompleted")


            self.fetchedResultsController.object(at: indexPath).sPriorityNumber =  self.fetchedResultsController.object(at: indexPath).sPreviousPN

            self.fetchedResultsController.object(at: indexPath).cellbackgroundColor = .white
            self.fetchedResultsController.object(at: indexPath).sPriorityColor = self.fetchedResultsController.object(at: indexPath).previousPriorityColor

            var error: NSError?


            do {
                // Save The object

                try self.moContext.save()
                print("SAVED")
            } catch let error1 as NSError {
                error = error1
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                UIView.transition(with: tableView,
                                  duration: 0.15,
                                  options: .transitionCrossDissolve,
                                  animations: { self.tableView.reloadData() })
            })

        }

        success(true)

    })

    closeAction.backgroundColor = UIColor(red:0.18, green:0.87, blue:0.65, alpha:1.0)

    return UISwipeActionsConfiguration(actions: [closeAction])

}

现在如何使用 FRC 委托方法 (.update) 以适当的动画刷新 tableView。

【问题讨论】:

  • 您需要使用 FRC 委托方法,这些方法记录在 here.
  • @pbasdf 我正在使用这些委托方法;但我真的不知道如何使用案例:更新方法。我正在更改一个函数中的 coreData 对象,该函数在单元格向右滑动时触发。现在我不知道如何使用 FRC 更新方法通过适当的动画来带来这些变化。
  • @pbasdf 刚刚用代码更新了问题!
  • self.tableView.moveRow(at: indexPath to:newIndexPath)。您可能还需要重新加载该行以删除该单元格上的滑动效果。
  • 因为最后一行已经是最后一行,FRC 不会将该更改视为move,而是update。所以添加代码来处理update changeType 通过调用reloadRows(at:)

标签: ios iphone uitableview core-data tableview


【解决方案1】:

你需要检查tableview功能**编辑风格**

【讨论】:

    【解决方案2】:

    表格视图控制器需要符合 NSFetchedResultsControllerDelegate 并实现其委托方法。如果配置正确,获取的结果控制器将监视托管对象上下文的更改并调用适当的委托方法以使用动画更新表格视图。

    class TaskTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
    
        var fetchedResultsController: NSFetchedResultsController<Task>!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            configureFetchedResultsController()
        }
    
        func configureFetchedResultsController() {
    
            if fetchedResultsController == nil {
    
                // 1. Get fetch request
                let fetchRequest: NSFetchRequest<Task> = Task.fetchRequest()
    
                // 2. Add sort descriptors
                fetchRequest.sortDescriptors = [NSSortDescriptor(key: "sPriorityNumber", ascending: false)]
    
                // 3. Configure the FRC
                fetchedResultsController = NSFetchedResultsController<Task>(fetchRequest: fetchRequest, managedObjectContext: CoreDataStack.context, sectionNameKeyPath: nil, cacheName: nil)
    
                // 4. Set the FRC delegate as self
                fetchedResultsController.delegate = self
            }
    
            // 5. Tell the FRC to start watching the MOC for changes
            do {
                try fetchedResultsController.performFetch()
            } catch {
                NSLog("Error starting fetched results controller  \(error)")
            }
        }
    
        // FRC delegate methods
    
        func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
                        didChange anObject: Any,
                        at indexPath: IndexPath?,
                        for type: NSFetchedResultsChangeType,
                        newIndexPath: IndexPath?) {
            switch type {
            case .insert:
                guard let newIndexPath = newIndexPath else { return }
                tableView.insertRows(at: [newIndexPath], with: .automatic)
            case .delete:
                guard let indexPath = indexPath else { return }
                tableView.deleteRows(at: [indexPath], with: .fade)
            case .move:
                tableView.reloadData()
            case .update:
                guard let indexPath = indexPath else { return }
                tableView.reloadRows(at: [indexPath], with: .automatic)
            }
        }
    
        func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
                        didChange sectionInfo: NSFetchedResultsSectionInfo,
                        atSectionIndex sectionIndex: Int,
                        for type: NSFetchedResultsChangeType) {
            switch type {
            case .delete:
                tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
            case .insert:
                tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
            default:
                break
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多