当有 2 个部分时,从 CoreData 填充部分中的行数

Posted

技术标签:

【中文标题】当有 2 个部分时,从 CoreData 填充部分中的行数【英文标题】:Populate Number of rows in section from CoreData when there are 2 sections 【发布时间】:2016-12-21 23:56:19 【问题描述】:

在我的 CoreData 中,我有一个 Person 实体,每个 Person 可以有多个(到多个)Statement 实体。语句实体有一个名为amountOwed 的属性,它是一个小数。现在我的想法是遍历所有数量并将它们加起来,如果它们是正数,则将它们添加到正数组中,如果它们是负数,则将它们添加到该数组中。然后使用该数组来计算每个部分需要显示多少个单元格。

我创建了一个 fetchedResultsController 并尝试将其用于 for 循环

for i in 0..<fetchedResultsController.fetchedObjects!.count 

        let person = fetchedResultsController.fetchedObjects?[i]

        let amountTotal = person?.value(forKeyPath: "statement.@sum.amountOwed") as? Decimal

        if(amountTotal! <= Decimal(0) )
        
            postiveCellNumber += 1
            print("\(postiveCellNumber) postive number count")
        
        else
            negativeCellNumber += 1
            print("\(negativeCellNumber) negative number count")
        

    

然后,我尝试在 numberOfRowsInSection 函数中使用这些数组,如下所示:

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    switch(section) 
    case 0:
        return postiveCellNumber
    case 1:
        return negativeCellNumber

    default :return 0
    

我认为我的 for 循环没有正确循环,因为我收到一条错误消息

索引 0 的部分中索引 2 处没有对象。

【问题讨论】:

您应该编辑您的问题以显示您的cellForRowAtIndexPath 方法。此外,postiveArraynegativeArray 是令人困惑的变量名称(因此,我输入了一个错误假设的答案)。您应该将名称更改为更有意义的名称,例如 positiveEntryCountnumberOfPositiveEntries。更好的办法是简单地将 Core Data 的正负结果填充到实际数组中。 Michael,只使用数字而不是数组的单元格数量的想法是,我希望 FetchedResultsController 仍然处理所有 ViewTable NSFetchedResultsControllerDelegate 操作。我更新了问题,以便更好地阅读 我在上一篇文章中给了你获取值的确切解决方案,但你仍然尝试使用不安全的方法来获取值... 【参考方案1】:

如何使用两个不同的查询,一个用于正值,一个用于负值,并带有两个不同的获取结果控制器?然后,您可以让 FRC 为您进行迭代和计数。

您将无法使用 FRC 来管理部分。你必须自己做。为 sectionNameKeyPath 指定 nil。然后你想要类似的东西

func numberOfSections(in tableView: UITableView) -> Int 
    return 2


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    if section == 0 
        return positiveResultsController.fetchedObjects?.count ?? 0
    
    else 
        return negativeResultsController.fetchedObjects?.count ?? 0
    

或许

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    if section == 0 
        let sectionInfo = positiveResultsController.sections![section]
        return sectionInfo.numberOfObjects
    
    else 
        let sectionInfo = negativeResultsController.sections![section]
        return sectionInfo.numberOfObjects
    

tableView(_:cellForRowAt:) 的逻辑类似。

【讨论】:

你能使用多个 FRC 来填充一个 tableView 吗?我被告知这可能是不可能的。 是的。您只需要注意您所在的部分,并使用正确的 FRC 进行交谈。确保您有不同的缓存名称。 我在尝试这个时遇到了这个问题:***.com/questions/41292064/… @Dmorgan 是对的,您需要自己管理 indexPath 部分。每当您被要求输入第 1 节时,您需要将该 indexPath 转换为从 [1, n] 到 [0, n] 并使用“其他”FRC。【参考方案2】:

如果不详细了解您的 FRC 和 tableView 是如何构造的,很难确定错误的具体原因。但这一点看起来很可疑:

    if(amountTotal! <= Decimal(0) )
    
        postiveCellNumber += 1
        print("\(postiveCellNumber) postive number count")
    

if 条件肯定是从后到前的:如果amountTotal! &gt;= Decimal(0),你应该增加positiveCellNumber?

但除此之外,即使您成功计算了计数,您也将面临计算每个部分的每一行中应该出现哪个 FRC 的 fetchedObjects 的问题:

您可以在 cellForRowAt 中“即时”执行此操作,但这将涉及再次遍历 fetchedObjects,以确定哪个出现在哪个部分中,这是笨拙且低效的。 在 FRC 完成其 performFetch 后,您可以一次性将 fetchedObjects 分成两个单独的数组。但是,每当更新 FRC 的 fetchedObjects 数组时,您就需要非常丑陋的 FRC 委托方法来更新这两个数组。 您可以将 FRC 配置为自动将其提取的对象分配给正确的部分,方法是为基础提取指定 sectionNameKeyPath 和关联的排序描述符。这里的问题是无法使用计算出的数字对获取进行排序。如果你想走这条路,你需要为你的Person实体添加一个totalAmountOwed属性,并确保在相关Statements发生变化时更新它。 或者,您可以按照@HalMueller 的建议,使用两个单独的FRC。您将对基础提取使用补充谓词,一个只获取那些Persons 的欠款为正数,另一个获得那些欠款为负数的谓词。然后,您可以使用一个 FRC 的 fetchedObjects 数组填充第 0 部分,并使用另一个 FRC 填充第 1 部分。总的来说,我认为这是我推荐的解决方案。

【讨论】:

谢谢!我将尝试 Hal 的想法。 你能用 2 个不同的 FRC 填充一个 tableView 吗? @icekomo 是的,这是完全可能的。在上面 Hal 的回答和您最近的其他问题/答案之间,您已经非常接近了。 @ pbasdf,谢谢,我认为我已经完成了这部分工作,但现在似乎陷入了这个领域:***.com/questions/41296550/… 这是我第一次使用 FRC,所以我对如何使用有点陌生它正在工作。

以上是关于当有 2 个部分时,从 CoreData 填充部分中的行数的主要内容,如果未能解决你的问题,请参考以下文章

如何从填充部分停止 objcopy

基于核心数据属性的 UITableView 部分

multipart/form-data 没有边界

如何更改从 NSFetchedResultsControler 填充的 UITableview 中部分的显示顺序?

UIPickerView 未填充从 CoreData 获取的数据

UICollectionView 中的多个部分