Last active
December 15, 2015 17:29
-
-
Save seanlilmateus/5296635 to your computer and use it in GitHub Desktop.
Countries example using Concurrency
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
class AppDelegate | |
def application(application, didFinishLaunchingWithOptions:launchOptions) | |
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win| | |
win.rootViewController = UINavigationController.alloc.initWithRootViewController(CountriesController.new) | |
win.backgroundColor = UIColor.whiteColor | |
win.makeKeyAndVisible | |
end | |
true | |
end | |
end |
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
class ArrayController | |
def initialize(array) | |
objects_collation NSArray.arrayWithArray(array.dup) | |
end | |
def sections | |
@collection | |
end | |
def objectAtIndexPath(indexPath) | |
@collection[indexPath.section][indexPath.row] | |
end | |
alias_method :[], :objectAtIndexPath | |
def sectionIndexTitleForSectionName(section_name) | |
@collection[section_name.upcase] | |
end | |
def sectionAtIndex(id) | |
@collection[id] || [] | |
end | |
def sectionIndexTitles | |
UILocalizedIndexedCollation.currentCollation.sectionTitles | |
end | |
def objects_collation(input) | |
selector = :name | |
index = sectionTitlesCount = UILocalizedIndexedCollation.currentCollation.sectionTitles.count | |
collation = UILocalizedIndexedCollation.currentCollation | |
mutable_sections = Array.new(sectionTitlesCount) { [] } | |
input.each do |object| | |
section_number = UILocalizedIndexedCollation.currentCollation.sectionForObject(object, collationStringSelector:selector) | |
mutable_sections[section_number] << object if object.is_a?(Country) | |
end | |
Dispatch::Queue.concurrent.apply(sectionTitlesCount) do |idx| | |
objects_for_section = mutable_sections[idx] | |
object = UILocalizedIndexedCollation.currentCollation.sortedArrayFromArray(objects_for_section, collationStringSelector:selector) | |
mutable_sections.replaceObjectAtIndex(idx, withObject:object) | |
end | |
@collection = mutable_sections | |
end | |
end |
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
class CountriesController < UITableViewController | |
def init | |
super.tap do | |
country_codes = NSLocale.ISOCountryCodes | |
locale = NSLocale.currentLocale | |
countries = country_codes.map do |iso_code| | |
country_name = locale.displayNameForKey(NSLocaleCountryCode, value:iso_code) | |
hash = { name: country_name, iso_code: iso_code } | |
Country.new hash | |
end | |
@countries = ArrayController.new(countries) | |
end | |
end | |
IDENTIFIER = "Countries Cell identifier" | |
def viewDidLoad | |
super | |
@image_queue = Dispatch::Queue.concurrent('de.mateus.image') | |
@image_op_queue = NSOperationQueue.new | |
@image_op_queue.name = ('de.mateus.image') | |
self.tableView.registerClass(UITableViewCell, forCellReuseIdentifier:IDENTIFIER) | |
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched | |
end | |
def numberOfSectionsInTableView(tbv) | |
@countries.sections.count | |
end | |
def tableView(tbv, numberOfRowsInSection:section) | |
@countries.sectionAtIndex(section).count | |
end | |
def sectionIndexTitlesForTableView(tbv) | |
@countries.sectionIndexTitles | |
end | |
def tableView(tbv, didSelectRowAtIndexPath:indexPath) | |
tbv.deselectRowAtIndexPath(indexPath, animated:true) | |
end | |
def tableView(tbv, titleForHeaderInSection:section) | |
@countries.sectionIndexTitles[section] | |
end | |
# A..Z# | |
def tableView(tbv, sectionForSectionIndexTitle:title, atIndex:index) | |
UILocalizedIndexedCollation.currentCollation.sectionForSectionIndexTitleAtIndex(index) | |
end | |
# to test the differents versions, you'll have to change the name of the tableView:cellForRowAtIndexPath: methods | |
def tableView(tbv, cellForRowAtIndexPath:indexPath) | |
tbv.dequeueReusableCellWithIdentifier(IDENTIFIER, forIndexPath:indexPath).tap do |cell| | |
country = @countries[indexPath] | |
cell.text = country.name | |
country.flag_image = UIImage.imageNamed(country.iso_code) | |
country.flag_image ||= UIImage.imageNamed('_united-nations') | |
cell.imageView.image = country.flag_image | |
end | |
end | |
# slow scrolling due of apply CIFilter in the Main Screen | |
def _1_tableView(tbv, cellForRowAtIndexPath:indexPath) | |
tbv.dequeueReusableCellWithIdentifier(IDENTIFIER, forIndexPath:indexPath).tap do |cell| | |
country = @countries[indexPath] | |
cell.text = country.name | |
country.flag_image ||= begin | |
image = UIImage.imageNamed(country.iso_code) || UIImage.imageNamed('_united-nations') | |
_, sepia_image = applySepiaFilter(image, indexPath) | |
sepia_image | |
end | |
cell.imageView.image = country.flag_image | |
end | |
end | |
# The GCD version may be a little buggy, sometimes you'll need to scroll to update the images | |
def _2_tableView(tbv, cellForRowAtIndexPath:indexPath) | |
tbv.dequeueReusableCellWithIdentifier(IDENTIFIER, forIndexPath:indexPath).tap do |cell| | |
country = @countries[indexPath] | |
country.indexPath = indexPath | |
cell.text = country.name | |
unless country.flag_image | |
@image_queue.async do | |
image = UIImage.imageNamed(country.iso_code) || UIImage.imageNamed('_united-nations') | |
index, sepia_image = applySepiaFilter(image, indexPath) | |
Dispatch::Queue.main.async do | |
@countries[index].flag_image = sepia_image | |
tbv.reloadRowsAtIndexPaths([index], withRowAnimation:UITableViewRowAnimationNone) | |
end | |
end | |
end | |
cell.imageView.image = country.flag_image | |
end | |
end | |
# NSOperationQueue Solution | |
def _3_tableView(tbv, cellForRowAtIndexPath:indexPath) | |
tbv.dequeueReusableCellWithIdentifier(IDENTIFIER, forIndexPath:indexPath).tap do |cell| | |
country = @countries[indexPath] | |
cell.text = country.name | |
unless country.flag_image | |
@image_op_queue.addOperationWithBlock(-> do | |
image = UIImage.imageNamed(country.iso_code) || UIImage.imageNamed('_united-nations') | |
index, sepia_image = applySepiaFilter(image, indexPath) | |
@countries[index].flag_image = sepia_image | |
operation = NSBlockOperation.blockOperationWithBlock(-> { | |
tbv.reloadRowsAtIndexPaths([indexPath], withRowAnimation:UITableViewRowAnimationNone) | |
}) | |
NSOperationQueue.mainQueue.addOperations([operation], waitUntilFinished:false) | |
end) | |
end | |
cell.imageView.image = country.flag_image | |
end | |
end | |
# Applies a Sepia CIFilter to given image, on the indexPath | |
# We need the indexPath to track the image and row | |
def applySepiaFilter(input_image, indexPath) | |
cii_image = CIImage.alloc.initWithImage(input_image) | |
filter = CIFilter.filterWithName("CISepiaTone") | |
filter.setDefaults | |
filter.setValue(cii_image, forKey:"inputImage") | |
filter.setValue(0.8, forKey:"inputIntensity") | |
output_image = filter.valueForKey('outputImage') | |
context = CIContext.contextWithOptions(nil) | |
image_ref = context.createCGImage(output_image, fromRect:output_image.extent) | |
[indexPath, UIImage.imageWithCGImage(image_ref)] | |
end | |
end |
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
class Country | |
attr_accessor :name, :iso_code, :flag_image | |
def initialize(dictionary={}) | |
setValuesForKeysWithDictionary(dictionary) if dictionary.is_a?(Hash) | |
end | |
def setValue(value, forUndefinedKey:key); end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the flags can be downloaded from here: https://www.gosquared.com/resources/flag-icons
you'll need the flags-iso/shiny/64 inside the zip file,
array_controller.rb is a helper I created for the UILocalizedIndexedCollation