需要帮助在 Swift 的 UITableView 中显示核心数据

Posted

技术标签:

【中文标题】需要帮助在 Swift 的 UITableView 中显示核心数据【英文标题】:Need Help displaying Core Data in a UITableView in Swift 【发布时间】:2016-10-02 20:12:52 【问题描述】:

如果这是一个重复的问题,请原谅。我尽我所能进行了彻底的搜索,但我在 UITableView 中看到的有关核心数据的其他问题似乎都不太适合我正在尝试做的事情。

基本上,我的核心数据中有两个“表”:

cstProjects 和 plProjects

两个表都有名为“propertyOwner”和“propertyID”(以及其他)的属性,它们被设置为字符串。

接下来,在 ViewController 中,我有一个表格视图实例,样式设置为 Subtitle,单元格标识符设置为“projectCell”。

因为我的核心数据中有两个表,所以我将表初始化为有两个部分。我希望第一部分显示 cstProjects 表中的所有项目,第二部分显示 plProjects 表中的所有项目。

到目前为止,这是我的 ViewController 代码。我已经把 cmets 放进去,尽我所能解释它。我创建的函数可能有点过分计算每个部分应该有多少“行”,但我不知道更简单的方法。

在下面的代码中,您可以看到双问号“??”是我不确定要放什么来显示我们当前正在迭代的项目类型的当前“行”的地方。

但最终,如果我必须尽可能简化我的问题,我只需要知道如何在 UITableView 中显示核心数据表的行。

import UIKit
import CoreData

class LoadProjectViewController: UIViewController, UITableViewDataSource, NSFetchedResultsControllerDelegate 

    let projectSectionCount: Int = 2
    let cstSection: Int = 0
    let plSection: Int = 1

    // Implement UITableViewDataSource methods
    func numberOfSectionsInTableView(tableView: UITableView) -> Int 
        return projectSectionCount
    

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        switch(section) 
        case cstSection:
            return getCSTProjects()
        case plSection:
            return getPLProjects()
        default:
            return 0
        
    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

        let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("projectCell")! as UITableViewCell

        switch (indexPath.section) 
            case cstSection:
                //this is where I need to set the property owner for the CST Project
                cell.textLabel!.text = ??

                //this is where I need to set the project ID for the CST Project
                cell.detailTextLabel!.text = ??
            case plSection:
                //this is where I need to set the property owner for the PL Project
                cell.textLabel!.text = ??

                //this is where I need to set the project ID for the PL Project
                cell.detailTextLabel!.text = ??

            default:
                cell.textLabel!.text = "Unknown"
        

        return cell
     

     func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
        switch section 
            case cstSection:
                return "Standing Timber Projects"
            case plSection:
                return "Purchased Logs"
            default:
                return "Unknown"
        
    


    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func getCSTProjects() -> Int 
         let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
         let context: NSManagedObjectContext = appDel.managedObjectContext
         let request = NSFetchRequest(entityName: "CSTProjects")
         var results = [AnyObject]()

        request.returnsObjectsAsFaults = false

        do 
            results = try context.executeFetchRequest(request)
         catch let error 
            print("There was an error loading the data. \(error)")
        

        if (results.count > 0) 
            return results.count
         else 
            return 0
        
    


    func getPLProjects() -> Int 
        let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
        let context: NSManagedObjectContext = appDel.managedObjectContext
        let request = NSFetchRequest(entityName: "PLProjects")
        var results = [AnyObject]()

        request.returnsObjectsAsFaults = false

        do 
            results = try context.executeFetchRequest(request)
         catch let error 
            print("There was an error loading the data. \(error)")
        

        if (results.count > 0) 
            return results.count
         else 
            return 0
        

    

【问题讨论】:

【参考方案1】:

在该方法中您需要做的第一件事是查找要显示的实例。为此,您应该修改 getCSTProjectsgetPLProjects 方法以保存获取请求的结果,而不是将它们丢弃。您可以通过向视图控制器添加新属性来保存数组来做到这一点。在相关说明中,您真的不想从 tableView(tableView:, numberOfRowsInSection:) 调用这些方法,因为该方法可以被调用很多次。在那里进行抓取几乎可以保证性能不佳。

要获取特定实例,请在您现在拥有的数组之一中查找它,使用 indexPath 参数获取数组索引。

一旦你有了那个特定的实例,你需要查找你在那些 Core Data 实体类型上声明的属性的值。放什么取决于你的CSTProjectsPLProjects 实体是如何定义的,以及你是否为它们创建了NSManagedObject 的子类。

例如,如果您的 CSTProjects 实体有一个名为 name 的字符串属性,您想将其用作标题,而您没有有一个 NSManagedObject 子类,您可以使用它:

cell.textLabel!.text = currentInstance.value(forKey: "name") as? String

如果你确实有一个 NSManagedObject 子类(这总是一个好主意),那就是

cell.textLabel!.text = currentInstance.name

【讨论】:

【参考方案2】:

与其尝试将两个实体(或表)合并到一个 fetchedResultsController 中,不如将数据放入一个表中并访问它会更容易。

如果表格足够相似,您可以在单个表格中使用类型代码来区分您需要的条目,例如使用过滤视图使表格看起来像另一种类型或另一种类型部分代码。这意味着将任何字段限制为一种类型的可选字段,以便其他字段可以忽略它们。然后 frc 可以使用代码字段作为分节符。

或者,如果表格完全不同,您可以添加第三个表格,例如 Projects,该表格具有与其他两个表格的可选一对一链接,并使用这些链接将 frc 从第三个表格中删除以填充字段在配置单元委托方法中的 tableView 中。

除了可以更轻松地构建当前的 frc 结构之外,如果您的需求在未来扩展,这些方法中的任何一种都会使添加第三种或第四种类型变得更加容易,并且可以避免因弯曲 API 以适应而不可避免地带来的复杂性不是为它设计的用途。

【讨论】:

以上是关于需要帮助在 Swift 的 UITableView 中显示核心数据的主要内容,如果未能解决你的问题,请参考以下文章

添加/删除 UITableView 选择到数组,复选标记在滚动时消失 - Swift

下拉刷新时 UITableview 出错,所有数据重复。任何人都可以帮助使用 Swift 3 , Xcode 8

UITableView Swift问题

UITableView Swift中带有布尔值的切换按钮

使用 swift 4 和 Alamofire 在 UITableView 中显示 JSON 数据 [关闭]

iOS swift 删除 UITableView 单元格分隔空间