Swift 2:使用两个 CoreData 实体填充 TableView

Posted

技术标签:

【中文标题】Swift 2:使用两个 CoreData 实体填充 TableView【英文标题】:Swift 2: Populating a TableView with two CoreData entities 【发布时间】:2017-02-23 06:32:55 【问题描述】:

这是我在网站上提出的第二个问题,因此我们非常感谢有关问题格式的任何反馈。话虽如此,这就是我的问题:

我正在尝试使用两个不同的 CoreData 实体填充此 tableview,但我不知道该怎么做。起初我尝试创建另一个对象并为 tableview 执行必要的方法,但它没有用。我试图用来自另一个实体的数据填充它,但我无法让 tableview 显示来自第二个实体的信息。我想知道是否有任何已知的惯例可以做到这一点。任何帮助深表感谢。

import UIKit
import CoreData

class DataEntryTableViewController: UITableViewController

@IBOutlet weak var menuButton: UIBarButtonItem!

@IBOutlet var listaMiembros: UITableView!

var object = [NSManagedObject]()

var dictionary: [String:String] = [
    "tipoVehiculo" :"",
    "ocupantes" :"",
    "numDeTablilla" :"",
    "jurisdiccion": "",
    "estado" :"",
    "vin" :"",
    "year" :"",
    "marca": "",
    "model" :"",
    "marbete" :"",
    "aseguradora" :"",
    "fechaCompra": "",
    "fechaExpiracion": "",
   ]

var objectNum = -1

@IBOutlet weak var listaMembers: UITableViewCell!
override func viewDidLoad() 

  super.viewDidLoad()
  listaMiembros.delegate = self
  listaMiembros.dataSource = self

    // Do any additional setup after loading the view, typically from a nib.
    //ADD SCROLL VIEW DIMENTIONS

    if revealViewController() != nil 
        menuButton.target = revealViewController()
      //  menuButton.action = "revealToggle:"
           menuButton.action = #selector(SWRevealViewController.revealToggle(_:))

        tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier: "Cell")

    


override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)

    //1
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    let managedContext = appDelegate.managedObjectContext

    //2       
    let fetchRequest = NSFetchRequest(entityName: "PageFour")

    //3
    do 
        let results = try managedContext.executeFetchRequest(fetchRequest)
        object = results as! [NSManagedObject]
     catch let error as NSError 
        print("Could not fetch \(error), \(error.userInfo)")
    

    self.tableView.reloadData()
    objectNum = -1
 

// MARK: UITableViewDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return object.count


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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
    let person = object[indexPath.row]
    cell!.textLabel!.text = person.valueForKey("numDeTablilla") as? String
   return cell!


override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    let indexPath = tableView.indexPathForSelectedRow // index path of selected cell

    let cellIndex = indexPath!.row // index of selected cell
    // print(indexPath?.row)//iT'S THE NUMBER YOU WANT - 1
    let cellName = tableView.cellForRowAtIndexPath(indexPath!) //  instance of selected cell
    objectNum = cellIndex + 1
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext
    let request = NSFetchRequest(entityName: "PageFour")
    request.returnsObjectsAsFaults = false
    do 
        try context.save()
     catch 
        print("There was a problem!")
    

    do 
        let results = try context.executeFetchRequest(request)
        if results.count > 0 

            for result in results as! [NSManagedObject] 

                if cellName?.textLabel?.text == result.valueForKey("numDeTablilla") as? String

                    dictionary["numDeTablilla"] = result.valueForKey("numDeTablilla") as? String
                    dictionary["marca"] = result.valueForKey("marcaField") as? String
                    dictionary["model"] = result.valueForKey("modeloField") as? String
                    dictionary["year"] = result.valueForKey("yearField") as? String
                    dictionary["tipoVehiculo"] = result.valueForKey("tipoVehiculo") as? String
                    dictionary["ocupantes"] = result.valueForKey("ocupantes") as? String
                    dictionary["jurisdiccion"] = result.valueForKey("jurisdicionVehiculo") as? String
                    dictionary["estado"] = result.valueForKey("estadoField") as? String
                    dictionary["vin"] = result.valueForKey("vinField") as? String
                    dictionary["marbete"] = result.valueForKey("numeroDeMarbete") as? String
                    dictionary["aseguradora"] = result.valueForKey("aseguradoraField") as? String
                    dictionary["fechaCompra"] = result.valueForKey("fechaCompraField") as? String
                    dictionary["fechaExpiracion"] = result.valueForKey("FechaExpiracionField") as? String

                
            
            performSegueWithIdentifier("EditVehicle", sender: self)
        

     catch 
        print("Fetch Failed")
    


 @IBAction func unwindToVC(segue: UIStoryboardSegue) 


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if (segue.identifier == "EditVehicle")
        //prepare for segue to the details view controller

        if let detailsVC = segue.destinationViewController as? NewVehicleController 
            // let indexPath = self.tableView.indexPathForSelectedRow

            detailsVC.dictionary = self.dictionary
            detailsVC.objectNum = self.objectNum
        
    
    //unnecessary for now
//        if(segue.identifier == "gotoNewData")
//            if let detailsVC = segue.destinationViewController as?         NewDataEntryTableViewController 
//                //detailsVC.dictionary = self.dictionary
//                detailsVC.objectNum = self.objectNum
//            
//        
    self.tableView.reloadData()    
  

【问题讨论】:

那么确切的问题是什么? 你能添加一张图片来显示你想要实现的目标吗? 我将其添加到问题中,但我也会在这里提及。我想用来自第二个实体的信息填充表格视图,但它不起作用,我不知道如何解决这个问题。 对第二个实体执行获取请求的代码部分在哪里? 【参考方案1】:

首先,不要保留 managedObjects。如果对象从访问的数据库中删除,将导致崩溃。最好使用自动跟踪插入、删除和更改的fetchedResultsController

对于您的问题,最简单的解决方案是将一种类型的实体放在一个部分中,将另一种类型的实体放在不同的部分中。 (您不需要有节标题,因此它可以显示为一个节)。您必须有两个不同的fetchedResultsController - 每个部分一个。而且你必须小心将你的 tableview indexPath 转换为正确的 fetchedResultsController indexPath - 但如果你只有两个部分,那并不难。

如果您希望不同的实体相互穿插,这要困难得多,但这是可能的。

另外,我不知道您为什么要在 didSelectRowAtIndexPath 中进行提取,这似乎是错误的。如果数据与 indexPath 处的 managedObject 相关,您应该能够通过关系获取所需的任何数据。

【讨论】:

我将只添加“实体相互穿插”:如果可能的话,为这些创建一个父实体,并确保在您的核心数据模型中它们都继承自该实体(有一个属性在核心数据 IB 中设置父实体)。然后只需在父级上创建一个获取请求,您将获得两个表的组合。 这是我正在寻找的信息。我会尽快处理并发布更新。感谢 Jon 和 Matic 的帮助! 我想知道是否可以手动添加一个单元格,其标题等于我想要从 coredata 实体获得的字段。那可能吗?如果是这样,我将如何添加单元格? 只是提供更新。我确实按照您的建议做了,并使用了两个获取的结果控制器并将每个控制器分配给一个部分。

以上是关于Swift 2:使用两个 CoreData 实体填充 TableView的主要内容,如果未能解决你的问题,请参考以下文章

保存/获取 CoreData 关系 Swift 3

在 Swift 中使用 MagicalRecord 实例化的向下转型 CoreData 实体

使用 CoreData 以编程方式创建实体/表,并在 Swift 3 for iOS 中将值插入该实体

使用 Swift 对两个数组进行排序

Swift & Core Data - 将实体添加到现有实体

为现有实体创建新的 CoreData 属性时 Swift 崩溃