The iOS framework that grows only as fast as its documentation
Model Tools

Classes

class  NIRadioGroup
 A general-purpose radio group. More...
 
protocol  <NIRadioGroupDelegate>
 The delegate for NIRadioGroup. More...
 
class  NIRadioGroupController
 A controller that displays the set of options in a radio group. More...
 
class  NITableViewActions
 The NITableViewActions class provides an interface for attaching actions to objects in a NITableViewModel. More...
 

Overview

Model tools are objects that abstract common functionality used in view controllers.

Radio Groups

One commonly-required feature for table views is radio button functionality. This is useful when you need the user to make a choice from a set of options. Implementing this is trivial with the Nimbus NIRadioGroup object.

The radio group object allows you to map a set of table objects to a group of identifiers and then support radio button interactions. You can find a working example of this in the ModelCatalog sample application.

Provided below is a quick overview of implementing the iOS Settings app's notifications page.

// We first define the enumeration of identifiers that we will use to map the table objects
// to unique identifiers.
typedef enum {
AppSortManual,
AppSortByTime,
} AppSort;
// You will create and retain a radio group object for the lifecycle of your controller.
@property (nonatomic, retain) NIRadioGroup* radioGroup;
- (void)refreshModel {
id manual = [NITitleCellObject cellWithTitle:@"Manually"];
id byTime = [NITitleCellObject cellWithTitle:@"By Time"];
NSArray* contents =
[NSArray arrayWithObjects:
@"Sort Apps:",
manual, byTime,
nil];
self.model = [[NITableViewModel alloc] initWithSectionedArray:contents
delegate:(id)[NICellFactory class]];
self.tableView.dataSource = self.model;
self.radioGroup = [[[NIRadioGroup alloc] init] autorelease];
// Selection notifications are sent through the delegate.
self.radioGroup.delegate = self;
// Map the objects to their corresponding identifiers.
[self.radioGroup mapObject:manual toIdentifier:AppSortManual];
[self.radioGroup mapObject:byTime toIdentifier:AppSortByTime];
// Set the initial selection.
self.radioGroup.selectedIdentifier = AppSortManual;
// Insert the radio group into the delegate call chain.
self.tableView.delegate = [self.radioGroup forwardingTo:self.tableView.delegate];
[self.tableView reloadData];
}
- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {
NSLog(@"Radio group selection changed: %d", identifier);
}

Table View Actions

Separating actions from presentation is an important aspect in simplifying table view cell design. It can be tempting to add delegate and selector properties to cells, but this ends up forcing a lot of logic to be written on the cell level so that the cells accurately represent their actionable state.

Nimbus provides a solution with NITableViewActions. NITableViewActions manages the cell <=> action mapping by inserting itself in the delegate call chain invocation forwarding. When cells are displayed, their accessoryType and selectionStyle are updated to reflect the actions that have been attached to them. When cells are tapped, the correct set of actions are performed.

Below is an example of implementing the "General" page of the Settings app.

// You will create and retain an actions object for the lifecycle of your controller.
@property (nonatomic, retain) NITableViewActions* actions;
- (void)refreshModel {
id about = [NITitleCellObject cellWithTitle:@"About"];
id softwareUpdate = [NITitleCellObject cellWithTitle:@"Software Update"];
NSArray* contents =
[NSArray arrayWithObjects:
@"",
about, softwareUpdate,
nil];
self.model = [[NITableViewModel alloc] initWithSectionedArray:contents
delegate:(id)[NICellFactory class]];
self.tableView.dataSource = self.model;
// The controller we provide here will be passed to the action blocks.
self.actions = [[[NITableViewActions alloc] initWithController:self] autorelease];
[self.actions attachNavigationAction:NIPushControllerAction([AboutViewController class])
toObject:about];
[self.actions attachNavigationAction:NIPushControllerAction([SoftwareUpdateViewController class])
toObject:softwareUpdate];
// Insert the actions into the delegate call chain.
self.tableView.delegate = [self.actions forwardingTo:self.tableView.delegate];
[self.tableView reloadData];
}