Created
April 9, 2016 01:31
-
-
Save hyperspacemark/5aca3f131781b6212e1e264b1f6478c0 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/// 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