使用 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 和行的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 使用 Swift 保存数据

Swift 3.0 使用Core Data

使用 Swift 使用 Core Data 对象填充 UIPickerView

Swift 3. 使用 Core Data 隐藏一个空的 tableView

iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储

searchDisplayController、UITableView、Core Data 和 Swift