使用 Core Data Swift 分割 TableView 和行

Posted

技术标签:

【中文标题】使用 Core Data Swift 分割 TableView 和行【英文标题】:Sectioning TableView and rows with Core Data Swift 【发布时间】:2014-09-15 16:50:04 【问题描述】:

我在 sqlite 中有两个表:

代码由 XCode Generation 生成:

class Event: NSManagedObject 

    @NSManaged var startDate: NSDate
    @NSManaged var details: EventDetail  //i think this property shoud be var details Array<EventDetail>  am i correct?


class EventDetail: NSManagedObject 

    @NSManaged var title: String
    @NSManaged var location: String
    @NSManaged var note: String
    @NSManaged var endDate: NSDate
    @NSManaged var event: NSManagedObject

我想将事件放在 section 中,将 eventDetails 放在 rows 中。

我创建了加载事件的方法:

var eventList : Array<AnyObject> = []

func loadEvents()
    let appDel : AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let moc: NSManagedObjectContext = appDel.managedObjectContext!
    let eventMO = NSFetchRequest(entityName: "Event")
    eventMO.returnsObjectsAsFaults = false

    var err : NSErrorPointer = nil
    eventList = moc.executeFetchRequest(eventMO, error: err)!
    self.tblEvento.reloadData()


func numberOfSectionsInTableView(tableView: UITableView!) -> Int 
    return eventList.count


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int        
    //return (eventList[section] as Event).details.count
   return //????? what can i put here

我不知道我可以在方法 numbertOfRowsInSection 中添加什么来定义该部分的行数。因为我无法访问 details.count 或类似的东西。

我认为还有其他方法可以做到这一点。我看到了一些使用 NSFetchedResultsController 但没有成功的东西。

我会很感激一些帮助。

【问题讨论】:

必须在 Core Data 模型检查器中将“详细信息”定义为 to-many 关系? – 然后你真的应该使用获取结果控制器。 嗨,马丁 R!我定义了它。你有一些带有 Fetched Results Controller 的示例吗?谢谢! 【参考方案1】:

提示:如果您使用 CoreData 和 UiTableView,请使用 NSFetchedResultsController 让事情变得更加简单。如果您正在寻找起点和示例代码 - 只需在 Xcode 中创建一个新的 master-detail-application 项目并在对话框中打开“Use Core Data”。

现在,直接回答您的问题:NSFetchResultsController 的“实现”示例:

var fetchedResultsController: NSFetchedResultsController

  if _fetchedResultsController != nil 
       return _fetchedResultsController!
   
   let fetchRequest = NSFetchRequest()
   // Edit the entity name as appropriate.
   let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext!)
   fetchRequest.entity = entity

   // Set the batch size to a suitable number.
   fetchRequest.fetchBatchSize = 20

   // Edit the sort key as appropriate.
   let sectionSortDescriptor = NSSortDescriptor(key: "startDate", ascending: true)
   let secondSortDescriptor = NSSortDescriptor(key: "title", ascending: true)

   let sortDescriptors = [sectionSortDescriptor, secondSortDescriptor]

   fetchRequest.sortDescriptors = sortDescriptors

   // Edit the section name key path and cache name if appropriate.
   // nil for section name key path means "no sections".
   let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: "startDate", cacheName: nil)
   aFetchedResultsController.delegate = self
   _fetchedResultsController = aFetchedResultsController

   var error: NSError? = nil
   if !_fetchedResultsController!.performFetch(&error) 
       // Replace this implementation with code to handle the error appropriately.
       // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
       //println("Unresolved error \(error), \(error.userInfo)")
       abort()
   

   return _fetchedResultsController!


// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return self.fetchedResultsController.sections?.count ?? 0


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
    return sectionInfo.numberOfObjects

【讨论】:

感谢您的回答!这个对我有用。只是这部分不起作用,但我做了一些更改,现在效果很好。如果 _fetchedResultsController != nil 返回 _fetchedResultsController! 爱你这个完全干净的答案:) 【参考方案2】:

根据crosscode的回答!

我做了一些改变!

1 - 我需要实现 NSFetchedResultsControllerDelegate 协议;

2 - 我需要声明 fechedResultsController

3 - 我需要在实体中为 NSEntityDescription 设置正确的表;

4 - 我需要在 sectionNameKeyPath

中按 startdate 导航到与组的关系

现在是代码:

//1 - implementing protocol
class AgendaViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate 

    //2 - declare the fechedResultsController
    var fetchedResultsController: NSFetchedResultsController = NSFetchedResultsController()

    override func viewDidLoad() 
        super.viewDidLoad()

        getFetchedResultController()       
    

    func getFetchedResultController() 

        let appDel : AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let moc: NSManagedObjectContext = appDel.managedObjectContext!

        let fetchRequest = NSFetchRequest()

        //3 - set the correct table
        let entity = NSEntityDescription.entityForName("EventDetail", inManagedObjectContext: moc)
        fetchRequest.entity = entity

        fetchRequest.fetchBatchSize = 20

        let sectionSortDescriptor = NSSortDescriptor(key: "event.startDate", ascending: true)

        let sortDescriptors = [sectionSortDescriptor] //, secondSortDescriptor]

        fetchRequest.sortDescriptors = sortDescriptors

        //4 - navigate in relationship to group by startdate 
        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "event.startDate", cacheName: nil)

        aFetchedResultsController.delegate = self
        self.fetchedResultsController = aFetchedResultsController

        var error: NSError? = nil
        if !self.fetchedResultsController.performFetch(&error) 
            abort()
        
    

    func numberOfSectionsInTableView(tableView: UITableView!) -> Int 
        return self.fetchedResultsController.sections?.count ?? 0
    

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
        return sectionInfo.numberOfObjects
    

【讨论】:

以上是关于使用 Core Data Swift 分割 TableView 和行的主要内容,如果未能解决你的问题,请参考以下文章