Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MartinJNash/7e19a2779547329d45e2 to your computer and use it in GitHub Desktop.
Save MartinJNash/7e19a2779547329d45e2 to your computer and use it in GitHub Desktop.
Treat a sectioned NSFetchedResults controller as a flat or linear collection.
import CoreData
extension NSFetchedResultsController {
var indexPaths: [NSIndexPath] {
var paths = [NSIndexPath]()
var sectionNumber = 0
for singleSection in sections as [NSFetchedResultsSectionInfo] {
for rowNumber in 0 ..< singleSection.numberOfObjects {
let path = NSIndexPath(forRow: rowNumber, inSection: sectionNumber)
paths.append(path)
}
sectionNumber++
}
return paths
}
func linearIndexForIndexPath(indexPath: NSIndexPath) -> Int? {
var currentLinearIndex = 0
var currentSection = 0
for singleSection in sections as [NSFetchedResultsSectionInfo] {
for rowNumber in 0 ..< singleSection.numberOfObjects {
if currentSection == indexPath.section && rowNumber == indexPath.row {
return currentLinearIndex
}
currentLinearIndex++
}
currentSection++
}
return nil
}
func indexPathAtLinerIndex(index: Int) -> NSIndexPath? {
if index < 0 {
return nil
}
var linearIndexAtBeginningOfSection: Int = 0
var sectionNumber: Int = 0
for singleSection in sections as [NSFetchedResultsSectionInfo] {
let distanceBetweenBeginningOfSectionAndDesiredIndex = index - linearIndexAtBeginningOfSection
// if linear index is in this section
if distanceBetweenBeginningOfSectionAndDesiredIndex < singleSection.numberOfObjects {
return NSIndexPath(forItem: distanceBetweenBeginningOfSectionAndDesiredIndex, inSection: sectionNumber)
}
linearIndexAtBeginningOfSection += singleSection.numberOfObjects
sectionNumber++
}
return nil
}
func objectAtLinearIndex(index: Int) -> AnyObject? {
if let ip = indexPathAtLinerIndex(index) {
return objectAtIndexPath(ip)
}
return nil
}
var objectCount: UInt {
let castSections = sections as [NSFetchedResultsSectionInfo]
return castSections.reduce(0, combine: { total, sectionInfo in total + sectionInfo.numberOfObjects })
}
var isEmpty: Bool {
return sections?.count == 0
}
var lastIndexPath: NSIndexPath? {
if let sections = sections as? [NSFetchedResultsSectionInfo] {
if let lastSection = sections.last {
let lastSectionNumber = sections.count - 1
let lastRowNumber = lastSection.numberOfObjects - 1
return NSIndexPath(forItem: lastRowNumber, inSection: lastSectionNumber)
}
}
return nil
}
func hasIndexPath(ip: NSIndexPath) -> Bool {
if ip.section < self.sections?.count {
if let sectionInfo = sections?[ip.section] as? NSFetchedResultsSectionInfo {
if ip.item < sectionInfo.numberOfObjects {
return true
}
}
}
return false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment