NSFetchedResultsController swift sections

5.7k views Asked by At

I have a table view that takes data from a CoreData entity with 3 fields. firstName: String, lastName: String and done:NSNumber (which is a UISwitch that can be turned ON or OFF).

I want to populate the table with the first and last names but first section is with names having the Switch ON, and a second section with names having the Switch OFF.

here is the code that saves the data:

class ViewController: UIViewController {
var context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
var newItem: List? = nil

@IBOutlet weak var txtFirst: UITextField!
@IBOutlet weak var txtLast: UITextField!
@IBOutlet weak var switchDone: UISwitch!

override func viewDidLoad() {
    super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
@IBAction func cancelTapped(sender: AnyObject) {
    dismissVC()
}
@IBAction func saveTapped(sender: AnyObject) {
    let context = self.context
    let ent = NSEntityDescription.entityForName("List", inManagedObjectContext: context)

    let nItem = List(entity: ent!, insertIntoManagedObjectContext: context)
    nItem.firstName = txtFirst.text
    nItem.lastName = txtLast.text
    nItem.done = switchDone.on
    context.save(nil)        
    dismissVC()
}
func dismissVC() {
    navigationController?.popViewControllerAnimated(true)
}
}

and here is the code that populates the table view:

class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate {

var context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!

var frc: NSFetchedResultsController = NSFetchedResultsController()

func getFetchedResultsController() -> NSFetchedResultsController {
    frc = NSFetchedResultsController(fetchRequest: listFetchRequest(), managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    return frc
}
func listFetchRequest() -> NSFetchRequest {
    let fetchRequest = NSFetchRequest(entityName: "List")
    let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]
    return fetchRequest
}
override func viewDidLoad() {
    super.viewDidLoad()
    frc = getFetchedResultsController()
    frc.delegate = self
    frc.performFetch(nil)
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.reloadData()
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    let numberOfSections = frc.sections?.count
    return numberOfSections!
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let numberOfRowsInSection = frc.sections?[section].numberOfObjects
    return numberOfRowsInSection!
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
    let list = frc.objectAtIndexPath(indexPath) as! List

    cell.textLabel?.text = list.firstName
    cell.detailTextLabel?.text = list.lastName

    return cell
}

}

I just can't figure out how to separate the data into the two sections based on the 'done' attribute.

1

There are 1 answers

0
pbasdf On BEST ANSWER

First, you need to sort your List objects by the done attribute, then the firstName:

let doneSortDescriptor = NSSortDescriptor(key: "done", ascending: true)
let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true)
fetchRequest.sortDescriptors = [doneSortDescriptor, sortDescriptor]

Then amend your Fetched Results Controller to get it to use the done attribute to define the sections:

frc = NSFetchedResultsController(fetchRequest: listFetchRequest(), managedObjectContext: context, sectionNameKeyPath: "done", cacheName: nil)

Finally, implement tableView:titleForHeaderInSection to set an appropriate title for each section.