Wednesday, February 18, 2009

Generic Selection List Controller

I've got another generic view controller for use in a Navigation-Based Application. This one is for having the user select one item from a list, like so:

This controller works exactly like the other generic ones I've posted. You create an instance, assign yourself as delegate and implement the delegate protocol, then push it onto the stack. The sole delegate method will be used to inform you of a new selection, if one was made. So, here's an example of creating an instance and putting it on the stack:

            SelectionListViewController *controller = [[SelectionListViewController alloc] init];
controller.delegate = self;
controller.list = myNSArrayWithAllPossibleSelections;
controller.initialSelection = theIndexOfTheCurrentlySelectedItem;
[self.navigationController pushViewController:controller animated:YES];
[controller release];

Then, we just need to implement the:

- (void)rowChosen:(NSInteger)row
{
myObject.selection = row;
[self.tableView reloadData];
}

Everything else is handled for you. Here's the code:

SelectionListViewController.h
//
// SelectionListViewController.h
// iContractor
//
// Created by Jeff LaMarche on 2/18/09.
//

#import <UIKit/UIKit.h>

@protocol SelectionListViewControllerDelegate <NSObject>
@required
- (void)rowChosen:(NSInteger)row;
@end


@interface SelectionListViewController : UITableViewController
{
NSArray *list;
NSIndexPath *lastIndexPath;
NSInteger initialSelection;

id <SelectionListViewControllerDelegate> delegate;
}

@property (nonatomic, retain) NSIndexPath *lastIndexPath;
@property (nonatomic, retain) NSArray *list;
@property NSInteger initialSelection;
@property (nonatomic, assign) id <SelectionListViewControllerDelegate> delegate;
@end



SelectionListViewController.m
//
// SelectionListViewController.m
// iContractor
//
// Created by Jeff LaMarche on 2/18/09.
//

#import "SelectionListViewController.h"

@implementation SelectionListViewController
@synthesize list;
@synthesize lastIndexPath;
@synthesize initialSelection;
@synthesize delegate;
-(IBAction)cancel
{
[self.navigationController popViewControllerAnimated:YES];
}

-(IBAction)save
{
[self.delegate rowChosen:[lastIndexPath row]];
[self.navigationController popViewControllerAnimated:YES];
}

#pragma mark -
- (id)initWithStyle:(UITableViewStyle)style
{
initialSelection = -1;
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated
{
// Check to see if user has indicated a row to be selected, and set it
if (initialSelection > - 1 && initialSelection < [list count])
{
NSUInteger newIndex[] = {0, initialSelection};
NSIndexPath *newPath = [[NSIndexPath alloc] initWithIndexes:newIndex length:2];
self.lastIndexPath = newPath;
[newPath release];
}


UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithTitle:NSLocalizedString(@"Cancel", @"Cancel - for button to cancel changes")
style:UIBarButtonItemStylePlain
target:self
action:@selector(cancel)]
;
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithTitle:NSLocalizedString(@"Save", @"Save - for button to save changes")
style:UIBarButtonItemStylePlain
target:self
action:@selector(save)]
;
self.navigationItem.rightBarButtonItem = saveButton;
[saveButton release];

[super viewWillAppear:animated];
}

- (void)dealloc
{
[list release];
[lastIndexPath release];
[super dealloc];
}

#pragma mark -
#pragma mark Tableview methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *SelectionListCellIdentifier = @"SelectionListCellIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SelectionListCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SelectionListCellIdentifier] autorelease];
}


NSUInteger row = [indexPath row];
NSUInteger oldRow = [lastIndexPath row];
cell.text = [list objectAtIndex:row];
cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

return cell;
}



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

int newRow = [indexPath row];
int oldRow = [lastIndexPath row];

if (newRow != oldRow)
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;

UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;

lastIndexPath = indexPath;
}


[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

@end


No comments:

Post a Comment