ios、swift、核心数据+多表

Posted

技术标签:

【中文标题】ios、swift、核心数据+多表【英文标题】:ios, swift, core data + multiple tables 【发布时间】:2014-10-20 08:19:14 【问题描述】:

我对 ios 和 swift 非常陌生。在单个视图上,如何将两个不同的获取请求发送到两个不同的表视图?我有一个类级别的 fetchReq 函数,它使用 NSPredicate 来获取参数并给我想要的各种结果。唯一知道哪个表是哪个表的地方是 tablView 函数,但看起来关于加载哪些数据的决定是在 viewDidLoad 上立即做出的。有没有好心人帮我重新构建核心数据代码,以便为每个表获得不同的提取请求?

import UIKit
import CoreData

class CustomTableViewCell : UITableViewCell 
    @IBOutlet var l1: UILabel?
    @IBOutlet var l2: UILabel?

    func loadItem(#number: String, name: String) 
        l1!.text = number
        l2!.text = name
    


class ViewController: UIViewController, UITableViewDelegate, NSFetchedResultsControllerDelegate, UITableViewDataSource 

    @IBOutlet var tableView1: UITableView!
    //this is my second table - Ive connected it in the IB to this VC. both tables work, but are identical
    @IBOutlet var tableView2: UITableView!
    let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
    var fetchedResultController: NSFetchedResultsController = NSFetchedResultsController()


    //the filtering happens inside this function. it gets called via didLoad, not cellsForRows
    func playerFetchRequest(playerType: String) -> NSFetchRequest 
        let fetchRequest = NSFetchRequest(entityName: "Players")
        let sortDescriptor = NSSortDescriptor(key: "number", ascending: true)
        let filter = NSPredicate(format: "%K = %@", "type", playerType)
        fetchRequest.sortDescriptors = [sortDescriptor]
        fetchRequest.predicate = filter
        return fetchRequest
    

    func getFetchedResultController() -> NSFetchedResultsController 
        fetchedResultController = NSFetchedResultsController(fetchRequest: playerFetchRequest(playerType), managedObjectContext:managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
        return fetchedResultController
    

    //remember: to create a table with multiple sections just implement the numberOfSectionsInTableView(_:) method
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if let numberOfRowsInSection = fetchedResultController.sections?[section].numberOfObjects
        return numberOfRowsInSection else return 0
    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        if (tableView == tableView2) 
        var playerType = "Forward"
        var cell:CustomTableViewCell = self.tableView1.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell
        let player = fetchedResultController.objectAtIndexPath(indexPath) as DataModel
        cell.l2?.text = player.lastName + ", " + player.firstName
        cell.l1?.text = player.number
        println(tableView)
        return cell
        
        else 
            var playerType = "Defender"
            var cell:CustomTableViewCell = self.tableView2.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell
            let player = fetchedResultController.objectAtIndexPath(indexPath) as DataModel
            cell.l2?.text = player.lastName + ", " + player.firstName
            cell.l1?.text = player.number
            println(tableView)
            return cell
        
    

    func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: NSIndexPath!) 
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        println("You selected cell #\(indexPath.row)!")
    

    override func viewDidLoad() 
        var nib = UINib(nibName: "CustomTableViewCell", bundle: nil)
        tableView1.registerNib(nib, forCellReuseIdentifier: "customCell")
        tableView2.registerNib(nib, forCellReuseIdentifier: "customCell")
        fetchedResultController = getFetchedResultController()
        fetchedResultController.delegate = self
        fetchedResultController.performFetch(nil)
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    
    func controllerDidChangeContent(controller: NSFetchedResultsController!) 
        tableView1.reloadData()
        tableView2.reloadData()
    

【问题讨论】:

两个答案都是正确的 - 非常感谢帮助新手! 【参考方案1】:

您需要 2 个 fetchedResultsControllers,每个表有两个不同的提取请求。如果您的表委托和数据源都是这个视图控制器,您需要切换并提供相应的内容...例如:

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

    if (tableView == tableView2)
    
        return fetchedResultController2.sections?[section].numberOfObjects
    
    else
    
        return fetchedResultController.sections?[section].numberOfObjects
    

另一种选择是创建 2 个自定义 MYTableViewDataSource 对象并将每个表视图的数据源设置为...当您遇到意外行为时,它可能会更明显并使数据更易于控制。

【讨论】:

【参考方案2】:

只需建立两个独立的 NSFetchedResultsController 对象,每个表一个:

var forwardFetchedResultController: NSFetchedResultsController
var defenderFetchedResultController: NSFetchedResultsController

然后在viewDidLoad 中为它们创建不同的 NSFetchRequest。在您的 tableView 函数中,为正确的表使用正确的获取结果控制器。

【讨论】:

以上是关于ios、swift、核心数据+多表的主要内容,如果未能解决你的问题,请参考以下文章

linux12 -MYSQL数据库 -->04 数据表单表多表查询--02

MySQL 基础之 单表多表联查

单表多表操作

数据库之表查询,单表多表,子查询

基表多表关系及子序列化

Excel多表多条件计数 countifs显示为0?