Swift CoreData:显示特定数据的最佳方法?

Posted

技术标签:

【中文标题】Swift CoreData:显示特定数据的最佳方法?【英文标题】:Swift CoreData: Best approach for showing specific data? 【发布时间】:2016-03-14 16:52:37 【问题描述】:

我进行了搜索,但仍然无法弄清楚如何做到这一点:

我有一个 tableViewVC,它显示了从 CoreData 实体检索到的数据列表(单元格):Person。该单元格仅显示每个数据条目的人名属性。

当我点击单元格 (func didSelectRowAtIndexPath) 时,它将转到 detailViewVC,我想在其中显示与该单个数据关联的其余属性的值(即年龄、性别、地址等)。

我本来想把名字的字符串值从VC1传给VC2,然后在VC2中做一些循环,根据名字属性搜索相关数据,但是如果名字在数据库中重复,这行不通。绝对是一个愚蠢的解决方法,这是行不通的。

所以我正在考虑使用每个数据条目的唯一 ID,例如 ObjectID?如果是这样,怎么办?另一种更好更有效的方法?

我是新手,所以请对我温柔和耐心。谢谢!

编辑:

VC1有tableview:

import CoreData

class vc1: UIViewController, UITableViewDataSource, UITableViewDelegate 
    ... ... ...

    var personData = [Person]()

    override func viewDidAppear(animated: Bool) 
        fetchAndSetResults()
        medTableView.reloadData()
    

    func fetchAndSetResults() 
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
        let fetchRequest = NSFetchRequest(entityName: "Person")

        do 
            let results = try context.executeFetchRequest(fetchRequest)
            self.personData = results as! [Person]
        

        catch let err as NSError 
            print(err.debugDescription)
        
    


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        if let cell = tableView.dequeueReusableCellWithIdentifier("PersonCell") as? PersonCell 

            let person = personData[indexPath.row]

            cell.configureCell(person) //custom func that shows the string value of attribute "name" of entity "Person" on an IBOutlet label.

            return cell
        

        else 
            return UITableViewCell()
        
    
    ... ...

    // Tapping a cell will present VC2_DetailView.
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
        let indexPath = tableView.indexPathForSelectedRow;
        let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! PersonCell

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VC2_DetailView") as! VC2_DetailView

        // Pass person's name in the tapped cell to the label.text in VC2_DetailView.
        vc.receivedPersonName = currentCell.cellPersonName.text

        //vc.view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
        //self.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

        // Adding dispatch_async to eliminate double tapping on cell. VC2 will be presented.
        dispatch_async(dispatch_get_main_queue(), 
            self.presentViewController(vc, animated: true, completion: nil)
        )
    
    ... ...


这样,当点击一个单元格时,将显示 VC2。我想要实现的是 VC2 将显示与该特定人的姓名相关联的其他属性,例如实体“Person”的“Age”和“Gender”,并在 VC2 的相关 IBOutlet 标签中显示它们。

更多信息:VC1 表有 3 个单元格:John、Jenny 和 Josh。当我单击 Jenny 时,VC2 将出现,并显示她的年龄和性别。 实体“Person”有 3 个属性:“name”、“age”和“gender”。

我是新手,非常感谢任何详细的解释!

【问题讨论】:

你想多了这个问题。该实体包含您需要的数据。您永远不需要像“对象 ID”或其他唯一标识符之类的东西。只需使用 NSManagedObject 数组,它将包含您需要的一切。使用原力,卢克。 我不明白。实体 Person 有许多人员数据。例如。 John、James、Jenny 等。我想进入仅显示 Jenny 详细信息的详细信息视图。能详细点吗? 查看此示例代码,说明如何将实体传递给 detailViewController。 developer.apple.com/library/ios/samplecode/CoreDataBooks/… 【参考方案1】:

你可以只传递实体本身。

【讨论】:

【参考方案2】:

好吧,伙计们,似乎没有人有兴趣帮助我深入。我以某种方式解决了我的问题:

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    //let indexPath = tableView.indexPathForSelectedRow;
    //let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! PersonCell

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewControllerWithIdentifier("VC2_DetailView") as! VC2_DetailView

    // Pass person's name in the tapped cell to the label.text in VC2_DetailView.

    // Get all data stored in the coredata[indexpath] on the same tapped cell.
    let person = personData[indextPath.row]
    vc.receivedPersonName = person.name
    vc.receivedPersonAge = person.age
    vc.receivedPersonGender = person.sex

    //vc.view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
    //self.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

    // Adding dispatch_async to eliminate double tapping on cell. VC2 will be presented.
    dispatch_async(dispatch_get_main_queue(), 
        self.presentViewController(vc, animated: true, completion: nil)
    )

基本上,我检索了特定数据的所有属性并将它们传递给 VC2。

我的下一个挑战将是如何编辑这些数据并保存/更新现有数据并避免创建新数据或重复数据。

谢谢大家,祝编码愉快!

【讨论】:

我建议直接传递 person 对象(所以是 vc.receivedPerson)。这避免了对 VC 在呈现的 VC 中显示的知识进行编码——它应该知道的是它需要一个人,而不是它究竟显示了那个人。 谢谢娄,你是对的。但是我通过发送索引使它更有效率。这样,我以后可以在 VC2 中为该特定数据实现编辑/更新函数。 效率不是更高——而是更低。传递实体和传递索引需要相同的时间——但是,当您只有一个索引时,您必须重新查找实体。此外,该行不是与对象永久关联的索引。 谢谢娄。事实上,当我实现按数据创建日期提取排序时,索引是一团糟。我现在在将数据保存为一种唯一 ID 时使用 NSDate。这用于在 VC2 中预测特定数据及其属性,以及在 VC3 中更新它们。 再次,我建议传递实体或 entity.objectID。保存日期不是对象的标识符。如果传递实体,代码会更简单、更快、更正确。【参考方案3】:

好吧,我实际上进一步简化了我的代码,以便在特定的 indexpath.row 上显示实体的详细信息。

当单元格被点击时:

// Let's try a new method by passing indexpath.row interger.
    let index = indexPath.row
    VC2.receivedIndex = index

因此,VC2 会从 VC1 接收被分接单元的索引号。

然后我在 VC2 中再次实现了实体的 fetchAndResults(),并且只需使用收到的索引号,我就能够在相关 label.text(s) 中显示该特定实体的所有详细信息。

对我来说,知道索引号(之前我问你是否有唯一的ObjectID,但我相信索引号是唯一的ID)比较好,所以以后我可以实现现有细节的更新功能。

干杯!

【讨论】:

我不会这样做。 indexPath.row 就是对象现在恰好在 fetch 中的位置。它不会与对象永久关联。重做一次提取并不是更有效(它要少得多)。我仍然建议通过实体。如果您必须传递一个 id,请使用实体的 objectID 属性——您可以使用它来获取实体——这需要更多的工作,因为您可能刚刚传递了实体。

以上是关于Swift CoreData:显示特定数据的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 从 CoreData sqlite 表中获取特定的行数据

swift3.0:CoreData的使用

Swift:Tableview 中特定单元格中的 addSublayer 不是每个单元格

将 swift 3 项目转换为使用 CoreData

如何在重置之前向日志添加值(CoreData 和 Swift)

这个 CoreData 如何在 swift 3 中获取?