Skip to content

Instantly share code, notes, and snippets.

@hyperspacemark
Created April 9, 2016 01:31
Show Gist options
  • Save hyperspacemark/5aca3f131781b6212e1e264b1f6478c0 to your computer and use it in GitHub Desktop.
Save hyperspacemark/5aca3f131781b6212e1e264b1f6478c0 to your computer and use it in GitHub Desktop.
/// Defines an interface for objects that can be collated.
protocol Collatable: Hashable {
/// The string value that will be used to collate objects.
var collationString: String { get }
}
final class LocalizedIndexedCollation<T: Collatable> {
// MARK: Properties
var numberOfSections: Int {
return sections.count
}
var sectionIndexTitles: [String]? {
return collation.sectionIndexTitles
}
private var indexPathsByObject = [T: NSIndexPath]()
// MARK: - Initialization
init(collatableObjects: [T]) {
let objects: [CollatedObject<T>] = collatableObjects.map(CollatedObject<T>.init)
let selector: Selector = Selector("collationString")
let sortedObjects = collation.sortedArray(array: objects, collationStringSelector: selector)
var sections = [[CollatedObject<T>]](count: collation.sectionIndexTitles.count, repeatedValue: [])
for sortedObject in sortedObjects {
let sectionIndex = collation.sectionForObject(sortedObject, collationStringSelector: selector)
sections[sectionIndex].append(sortedObject)
let indexPath = NSIndexPath(forRow: sections[sectionIndex].endIndex - 1, inSection: sectionIndex)
indexPathsByObject[sortedObject.object] = indexPath
}
self.sections = sections
}
// MARK: Methods
func numberOfRowsInSection(section: Int) -> Int {
return sections[section].count
}
func titleForSection(section: Int) -> String? {
if sections[section].isEmpty {
return nil
} else {
return collation.sectionTitles[section]
}
}
func sectionForSectionIndexTitleAtIndex(index: Int) -> Int {
return collation.sectionForSectionIndexTitleAtIndex(index)
}
func itemAtIndexPath(indexPath: NSIndexPath) -> T {
return sections[indexPath.section][indexPath.row].object
}
func indexPathForObject(object: T) -> NSIndexPath? {
return indexPathsByObject[object]
}
// MARK: - Private
private let sections: [[CollatedObject<T>]]
private let collation: UILocalizedIndexedCollation = UILocalizedIndexedCollation.currentCollation()
}
private class CollatedObject<T: Collatable>: NSObject {
let object: T
dynamic let collationString: String
init(object: T) {
self.object = object
self.collationString = object.collationString
super.init()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment