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 表中获取特定的行数据
Swift:Tableview 中特定单元格中的 addSublayer 不是每个单元格