Last active
August 29, 2015 14:09
-
-
Save MartinJNash/7e19a2779547329d45e2 to your computer and use it in GitHub Desktop.
Treat a sectioned NSFetchedResults controller as a flat or linear collection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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