Created
February 14, 2014 19:18
-
-
Save kharmabum/9007199 to your computer and use it in GitHub Desktop.
For selecting mutually exclusive categories in a dependent hierarchy (i.e. tracing a taxonomy). See -> http://www.cocoanetics.com/2011/03/expandingcollapsing-tableview-sections/
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 <UIKit/UIKit.h> | |
@interface HPGroupSelectViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> | |
@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
#import "HPGroupSelectViewController.h" | |
#import "DTCustomColoredAccessory.h" | |
#import "HPActionBar.h" | |
#import "HPApiClient.h" | |
#import "MBProgressHUD.h" | |
#import "HPUI.h" | |
#import "HPTitleLabel.h" | |
#import "HPUser.h" | |
@interface HPGroupSelectViewController () | |
@property (strong, nonatomic) NSArray *sectionTitles; | |
@property (strong, nonatomic) NSMutableDictionary *selections; | |
@property (nonatomic, strong) NSMutableIndexSet *expandedSections; | |
@property (nonatomic, strong) UITableView *tableView; | |
@property (strong, nonatomic) HPTitleLabel *titleLabel; | |
@property (nonatomic, strong) NSDictionary *buildings; | |
@property (nonatomic, strong) NSArray *locations; | |
@property (nonatomic, strong) NSArray *departments; | |
@property (nonatomic, strong) NSDictionary *organizations; | |
@end | |
@implementation HPGroupSelectViewController | |
#pragma mark - UITableViewDataSource | |
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
if (indexPath.row == 0) { | |
return ([self currentSelectionFromSection:indexPath.section]) ? 60 : 44; | |
} else { | |
return 38; | |
} | |
} | |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView | |
{ | |
return 4; | |
} | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section | |
{ | |
return (![self.expandedSections containsIndex:section]) ? 1 : [self itemsForSection:section].count + 1; | |
} | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
UITableViewCell *cell; | |
NSString *currentSelection = [self currentSelectionFromSection:indexPath.section]; | |
if (indexPath.row == 0) { | |
cell = [tableView dequeueReusableCellWithIdentifier:@"SectionCell"]; | |
cell.accessoryView=nil; | |
if (!cell) { | |
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"SectionCell"]; | |
cell.selectionStyle = UITableViewCellSelectionStyleNone; | |
cell.textLabel.font = [HPUI fontWithName:@"Ronnia-SemiBold" size:20.0f]; | |
cell.detailTextLabel.font = [HPUI fontWithName:@"Ronnia-Light" size:16.0f]; | |
} | |
cell.textLabel.text = self.sectionTitles[indexPath.section]; | |
cell.detailTextLabel.text = currentSelection; | |
DTCustomColoredAccessoryType accessoryType = ([self.expandedSections containsIndex:indexPath.section]) ? DTCustomColoredAccessoryTypeUp : DTCustomColoredAccessoryTypeDown; | |
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:accessoryType]; | |
cell.accessoryView.userInteractionEnabled = NO; | |
cell.contentView.alpha = 1; | |
if (indexPath.section == 1 || indexPath.section == 3) { | |
if (![self currentSelectionFromSection:indexPath.section - 1]) cell.contentView.alpha = 0.4; | |
} | |
} else { | |
cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"]; | |
cell.accessoryView=nil; | |
if (!cell) { | |
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ItemCell"]; | |
cell.selectionStyle = UITableViewCellSelectionStyleGray; | |
cell.textLabel.font = [HPUI fontWithName:@"Ronnia-Regular" size:16.0f]; | |
cell.textLabel.xOrigin += 20; | |
} | |
NSArray *sectionItems = [self itemsForSection:indexPath.section]; | |
NSString *item = [sectionItems objectAtIndex:indexPath.row - 1]; | |
cell.textLabel.text = [NSString stringWithFormat:@" %@", item]; | |
cell.accessoryType = ([item isEqual:currentSelection]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; | |
} | |
return cell; | |
} | |
#pragma mark - UITableView Delegate | |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
if (!indexPath.row) { | |
[self toggleSection:indexPath tableView:tableView]; | |
} else { | |
NSArray *sectionItems = [self itemsForSection:indexPath.section]; | |
NSString *currentSelection = self.selections[self.sectionTitles[indexPath.section]]; | |
if (![currentSelection isEqual:[sectionItems objectAtIndex:indexPath.row - 1]]) { | |
self.selections[self.sectionTitles[indexPath.section]] = [sectionItems objectAtIndex:indexPath.row - 1]; | |
} else { | |
[self.selections removeObjectForKey:self.sectionTitles[indexPath.section]]; | |
} | |
if (indexPath.section == 0 || indexPath.section == 2) | |
[self.selections removeObjectForKey:self.sectionTitles[indexPath.section + 1]]; | |
NSInteger countChild = (indexPath.section == 0 || indexPath.section == 2) ? 1 : 0; | |
[self.expandedSections removeIndex:indexPath.section]; | |
[self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(indexPath.section, 1 + countChild)] withRowAnimation:NO]; | |
} | |
[tableView deselectRowAtIndexPath:indexPath animated:YES]; | |
} | |
#pragma mark - Private | |
- (NSArray *)itemsForSection:(NSInteger)index | |
{ | |
switch (index) { | |
case 0: | |
return self.departments; | |
case 1: | |
return [self.organizations objectForKey:[self currentSelectionFromSection:0]]; | |
case 2: | |
return self.locations; | |
case 3: | |
return [self.buildings objectForKey:[self currentSelectionFromSection:2]]; | |
default: | |
return nil; | |
} | |
} | |
- (NSString *)currentSelectionFromSection:(NSInteger)index | |
{ | |
return self.selections[self.sectionTitles[index]]; | |
} | |
-(void)toggleSection:(NSIndexPath*)indexPath tableView:(UITableView *)tableView | |
{ | |
if ((indexPath.section == 1 || indexPath.section == 3) && ![self currentSelectionFromSection:indexPath.section - 1]) | |
return; | |
BOOL currentlyExpanded = [self.expandedSections containsIndex:indexPath.section]; | |
if (currentlyExpanded) | |
[self.expandedSections removeIndex:indexPath.section]; | |
else | |
[self.expandedSections addIndex:indexPath.section]; | |
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; | |
DTCustomColoredAccessoryType accessoryType = (!currentlyExpanded) ? DTCustomColoredAccessoryTypeUp : DTCustomColoredAccessoryTypeDown; | |
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:accessoryType]; | |
cell.accessoryView.userInteractionEnabled = NO; | |
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:NO]; | |
} | |
-(void)didPressCancelButtonOnGroupEdit:(id)sender | |
{ | |
[self.navigationController dismissModalViewControllerAnimated:YES]; | |
} | |
- (void)failWithMessage:(NSString *)status | |
{ | |
[MBProgressHUD hideHUDForView:self.view animated:YES]; | |
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:NO]; | |
[hud setLabelText:status]; | |
[self performBlockOnMainThread:^{ | |
[MBProgressHUD hideHUDForView:self.view animated:YES]; | |
[self performBlockOnMainThread:^{hud.labelText = @"";} afterDelay:0.33f]; | |
} afterDelay:1.5f]; | |
} | |
-(void)finishSelectingGroup | |
{ | |
[MBProgressHUD showHUDAddedTo:self.view animated:YES]; | |
NSMutableArray *savedGroups = [NSMutableArray arrayWithCapacity:4]; | |
for (int i = 0; i < 4; i++) { | |
NSString *selection = [self currentSelectionFromSection:i]; | |
if (selection) [savedGroups addObject:selection]; | |
} | |
[HPApiClient saveGroupList:savedGroups success:^(NSDictionary *results) { | |
[MBProgressHUD hideAllHUDsForView: self.view animated:YES]; | |
[self dismissModalViewControllerAnimated:YES]; | |
[HPSessionManager activeUser].groups = [results objectForKey:@"groups"]; | |
} failure:^(NSString *status, id json) { | |
[self failWithMessage:status]; | |
}]; | |
} | |
#pragma mark - VC Lifecycle | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
self.expandedSections = [[NSMutableIndexSet alloc] init]; | |
self.sectionTitles = @[@"Departments", @"Organizations", @"Locations", @"Buildings"]; | |
self.selections = [[NSMutableDictionary alloc] initWithCapacity:4]; | |
self.titleLabel = [[HPTitleLabel alloc] init]; | |
self.navigationItem.titleView = self.titleLabel; | |
[self.titleLabel setTitleLabelText:@"Edit Groups"]; | |
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped]; | |
self.tableView.delegate = self; | |
self.tableView.dataSource = self; | |
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; | |
self.tableView.yOrigin = 0; | |
self.tableView.height = self.view.height - self.navigationController.navigationBar.height - 44; | |
self.tableView.backgroundView = nil; | |
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageFromDiskNamed:@"gray_bg.png"]]; | |
[self.view addSubview:self.tableView]; | |
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(didPressCancelButtonOnGroupEdit:)]; | |
HPActionBar *actionBar = [[HPActionBar alloc] initWithButtonType: HPTabbarActionButtonCheckMark]; | |
[actionBar.actionButton setTarget:self action:@selector(finishSelectingGroup) forControlEvents:UIControlEventTouchUpInside]; | |
actionBar.yOrigin = self.view.height - 44 - actionBar.height; | |
[self.view addSubview: actionBar]; | |
[MBProgressHUD showHUDAddedTo:self.view animated:YES]; | |
[HPApiClient getGroupList:^(NSDictionary *results) { | |
[MBProgressHUD hideAllHUDsForView:self.view animated:YES]; | |
NSDictionary *groups = results[@"groups"]; | |
self.departments = groups[@"Departments"]; | |
self.organizations = groups[@"Organizations"]; | |
self.locations = groups[@"Locations"]; | |
self.buildings = groups[@"Buildings"]; | |
self.expandedSections = [[NSMutableIndexSet alloc] init]; | |
[self.tableView reloadData]; | |
} failure:^(NSString *status, id json) { | |
[self failWithMessage:status]; | |
}]; | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment