Autogroup UITableView alphabetically Autogroup UITableView alphabetically objective-c objective-c

Autogroup UITableView alphabetically


First of All Define sections

self.sections = [NSArray arrayWithObjects:@"#", @"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"u", @"v", @"w", @"x", @"y", @"z", nil];

then

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{   return 27;}- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{   return self.sections;}    - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString*)title atIndex:(NSInteger)index{   return index;}- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {   return [self.sections objectAtIndex:section];}

After that filter by alphabets

NSArray *sectionArray = [vendorList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", [self.sections objectAtIndex:section]]];             rowCount = [sectionArray count];


I have a pod just for this:

https://github.com/chrisladd/CGLAlphabetizer/

pod 'CGLAlphabetizer', '~> 0.1'

It creates a dictionary of arrays keyed by letters of the alphabet from a single array of objects and an arbitrary keyPath.

alphabetizedDictionary = [CGLAlphabetizer alphabetizedDictionaryFromObjects:anArray usingKeyPath:@"keyPath"];

So, assuming you had the model object that looked like this:

@interface CGLContact : NSObject@property (nonatomic) NSString *firstName;@property (nonatomic) NSString *lastName;@property (nonatomic, readonly) NSString *fullName;@end

Your tableViewController implementation might look something like this:

static NSString * const CGLContactsCellIdentifier = @"CGLContactsCellIdentifier";@interface CGLContactsTableViewController ()@property (nonatomic) NSDictionary *alphabetizedDictionary;@property (nonatomic) NSArray *sectionIndexTitles;@end@implementation CGLContactsTableViewController- (void)viewDidLoad {    [super viewDidLoad];    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CGLContactsCellIdentifier];}- (void)setContacts:(NSArray *)contacts {    _contacts = contacts;    self.alphabetizedDictionary = [CGLAlphabetizer alphabetizedDictionaryFromObjects:_contacts usingKeyPath:@"lastName"];    self.sectionIndexTitles = [CGLAlphabetizer indexTitlesFromAlphabetizedDictionary:self.alphabetizedDictionary];    [self.tableView reloadData];}- (CGLContact *)objectAtIndexPath:(NSIndexPath *)indexPath {    NSString *sectionIndexTitle = self.sectionIndexTitles[indexPath.section];    return self.alphabetizedDictionary[sectionIndexTitle][indexPath.row];}#pragma mark - Table view data source- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {    return self.sectionIndexTitles;}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {    return [self.sectionIndexTitles count];}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    NSString *sectionIndexTitle = self.sectionIndexTitles[section];    return [self.alphabetizedDictionary[sectionIndexTitle] count];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CGLContactsCellIdentifier forIndexPath:indexPath];    CGLContact *contact = [self objectAtIndexPath:indexPath];    cell.textLabel.text = contact.fullName;    return cell;}@end

Populated with every human who has gone to space:

demo


i did the following:

AutoSectionTableViewDataSource.h

@protocol AutoSectionTableViewDataSource- (NSString*)tableView:(UITableView*)tableView sectionNameAtIndexPath:(NSIndexPath*)indexPath;@end@interface AutoSectionTableViewDataSource : NSObject <UITableViewDataSource>- (id)initWithDataSource:(NSObject<UITableViewDataSource,AutoSectionTableViewDataSource>*)dataSource;@end

AutoSectionTableViewDataSource.m

@interface AutoSectionTableViewDataSource ()@property(weak) NSObject<UITableViewDataSource,AutoSectionTableViewDataSource> *dataSource;@end@implementation AutoSectionTableViewDataSource- (id)initWithDataSource:(NSObject<UITableViewDataSource,AutoSectionTableViewDataSource>*)dataSource{    self = [super init];    self.dataSource = dataSource;    return self;}- (BOOL)respondsToSelector:(SEL)selector{    if ([super respondsToSelector:selector]) return YES;    if (self.dataSource && [self.dataSource respondsToSelector:selector]) return YES;    return NO;}- (void)forwardInvocation:(NSInvocation*)invocation{    if (self.dataSource && [self.dataSource respondsToSelector:invocation.selector]) {        [invocation invokeWithTarget:self.dataSource];    } else {        [self doesNotRecognizeSelector:invocation.selector];    }}- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector{    if (self.dataSource) return [self.dataSource methodSignatureForSelector:selector];    return nil;}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0];    NSMutableSet *set = [[NSMutableSet alloc] init];    for (NSInteger row=0; row<rows; row++) {        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];        NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath];        [set addObject:sectionName];    }    return set.count;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0];    NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init];    NSInteger count = 0;    for (NSInteger row=0; row<rows; row++) {        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];        NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath];        if (!tmp[sectionName]) {            tmp[sectionName] = @(tmp.count);        }        if ([tmp[sectionName] intValue] == section) {            count++;        }    }    return count;}- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0];    NSMutableSet *set = [[NSMutableSet alloc] init];    for (NSInteger row=0; row<rows; row++) {        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];        NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath];        if (![set containsObject:sectionName]) {            [set addObject:sectionName];            if (set.count - 1 == section) {                //NSLog(@"AutoSectionTableViewDataSource titleForHeaderInSection:%d -> %@", section, sectionName);                return sectionName;            }        }    }    return nil;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0];    NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init];    NSInteger count = 0;    for (NSInteger row=0; row<rows; row++) {        NSIndexPath *rowIndexPath = [NSIndexPath indexPathForRow:row inSection:0];        NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:rowIndexPath];        if (!tmp[sectionName]) {            tmp[sectionName] = @(tmp.count);        }        if ([tmp[sectionName] intValue] == indexPath.section) {            count++;            if (count-1 == indexPath.row) {                UITableViewCell *cell = [self.dataSource tableView:tableView cellForRowAtIndexPath:rowIndexPath];                return cell;            }        }    }    return nil;}@end

and then in your code:

- (NSString*)tableView:(UITableView *)tableView sectionNameAtIndexPath:(NSIndexPath *)indexPath{    return @"this would be your section name for indexPath.row"}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return total_number_of_rows;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    return cell_for_indexPath.row;}- (void)viewDidLoad{    [super viewDidLoad];    // instead of self.tableView.dataSource = self; use:    self.autoSectionDataSource = [[AutoSectionTableViewDataSource alloc] initWithDataSource:self];    self.tableView.dataSource = self.autoSectionDataSource;}