Reputation: 111
I am trying to group section 0 my tableView by the "category" attribute of an item.
Example:
Drinks: (item.category = header)
Dr. Prepper
Coke
Pepsi
Kitchen: (item.category = header)
Pots
Pans...etc.
CrossOff(header)
items
I still want section1 to be the item.slcross (or the last section if each group has to be their own section...and it doesn't have to be grouped).
When I change the secondarySortDescriptor key from "slitem" to "slcategory" and use the sectionHeader code below, it returns "nil". I also tried using
let sectionHeader2 = "\(item.valueForKeyPath("slcategory"))"
but still had the same effect with both "slitem" and "slcategory".
Do I have to use a sort descriptor for each category or is there a way to make it pull the category attribute for the item and group the like categories together?
FRC set up:
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc : NSFetchedResultsController = NSFetchedResultsController()
var selectedItem : List?
func itemFetchRequest() -> NSFetchRequest{
let fetchRequest = NSFetchRequest(entityName: "List")
let primarySortDescription = NSSortDescriptor(key: "slcross", ascending: true)
let secondarySortDescription = NSSortDescriptor(key: "slitem", ascending: true)
fetchRequest.sortDescriptors = [primarySortDescription, secondarySortDescription]
fetchRequest.predicate = NSPredicate(format:"slist == true")
return fetchRequest
}
func getFetchRequetController() ->NSFetchedResultsController{
frc = NSFetchedResultsController(fetchRequest: itemFetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "slcross", cacheName: nil)
return frc
}
TableViewHeaders:
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
let entityDescription = NSEntityDescription.entityForName("List", inManagedObjectContext: moc)
let item = List(entity: entityDescription!, insertIntoManagedObjectContext: moc)
let sectionHeader = "\(item.slcategory)"
let sectionHeader1 = "Items in Cart - #\(frc.sections![section].numberOfObjects)"
if (frc.sections!.count > 0) {
let sectionInfo = frc.sections![section]
if (sectionInfo.name == "0") {
return sectionHeader2
} else {
return sectionHeader1
}
} else {
return nil
}
}
Upvotes: 1
Views: 96
Reputation: 21536
There are a few ways to do this, but probably the easiest is to add a new method to your NSManagedObject
subclass. The method returns a string which will be used as the title for the section; so if slcross
is false, it returns the value of slcategory
, and if slcross
is true it returns "True":
func sectionIdentifier() -> String {
if (self.slcross) {
return "True"
} else {
return "\(self.slcategory)"
}
}
(Note this code goes in your List
class definition, not your view controller).
In the view controller, use this sectionIdentifier
as the sectionNameKeyPath
for your FRC:
frc = NSFetchedResultsController(fetchRequest: itemFetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "sectionIdentifier", cacheName: nil)
For that to work, it is imperative that the objects are sorted correctly: first by slcross
, then by slcategory
:
let primarySortDescription = NSSortDescriptor(key: "slcross", ascending: true)
let secondarySortDescription = NSSortDescriptor(key: "slcategory", ascending: true)
Finally, amend your titleForHeaderInSection
to use the section name (which the FRC gets from sectionIdentifier
), but replacing the "True" with your computed string:
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
if (frc.sections!.count > 0) {
let sectionInfo = frc.sections![section]
if (sectionInfo.name == "True") {
return "Items in Cart - #\(sectionInfo.numberOfObjects)"
} else {
return sectionInfo.name
}
} else {
return nil
}
}
Upvotes: 1
Reputation: 4583
From Apple Docs...
When you initialize the fetch results controller, you provide four parameters: ..... ....Optionally, a key path on result objects that returns the section name. The controller uses the key path to split the results into sections (passing nil indicates that the controller should generate a single section)..... After creating an instance, you invoke performFetch: to actually execute the fetch.
If you want to sort the sections by category then you need to make the sectionNameKeyPath argument in the NSFetchedResultsController
init to be your "category" property instead of your "slcross" property.
When I've used this in the past I've also included that same property that I've set as the sectionNameKeyPath in my sort descriptors, but not sure if that is actually needed or not.
Hope I have answered your question?
Upvotes: 0