Creating the Controls - the Base Classes

Each locale-aware control is implemented as a UITableView cell, which is extended by MAF using the MAFTableViewCell class. The MAFTableViewCell class uses MAF skinning and MAF formatters, and provides value help functionality to table view cells.

To create and use MAF locale-aware controls, first instantiate the MAFValueHelpMediator class. This class builds and initializes each locale-aware control and sets the input formatting settings and predefined value help lists, that is, the set of values users can pick from.

This mediator class also behaves as the communication bridge between the application and the controls. Each action triggered in a locale-aware control is first handled by the MAF library on the lower level. Next, the mediator sends the relevant messages to the application via the MAFValueHelpMediatorDelegate and the MAFValueHelpControllerDelegate methods. These delegate messages:
  • Indicate to the application when a user taps a part of a locale-aware control that pops up a screen with the values users can select from. The mediator calls the local aware control’s registered delegate because the control is created by the mediator and is not connected to its parent view. The mediator can display the value help screen by requesting its delegate, so if you set the application’s view controller class as the delegate, the mediator requests the delegate to present the value help screen.
  • Indicate when a user selects a value from the help screen.
  • Indicate when to dismiss the help screen (this is called immediately after the value selection signal).
To make an application respond to these interactions, the MySampleViewController must implement the MAFValueHelpMediatorDelegate and the MAFValueHelpControllerDelegate protocols. First, extend the definition in the header file:
@interface MySampleViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, MAFValueHelpMediatorDelegate,MAFValueHelpControllerDelegate>{}
@end
To create an implementation for MAFValueHelpMediatorDelegate and a MAFValueHelpControllerDelegate, add this code in the implementation file of the MySampleViewController class:
// MAFValueHelpMediatorDelegate implementation

- (void)valueHelpMediator:(MAFValueHelpMediator *)sender requestsDisplayOfValueHelpController:(MAFValueHelpController *)controller requestor:(UIView *)requestor
{
    controller.delegate = self; // set self as the handler for controller, for dismissing modal presentation
    [self presentModalViewController:controller animated:YES]; // use modal view controller
}

- (void)valueHelpMediator:(MAFValueHelpMediator *)sender didEditValueOfAccessor:(id<MAFValueHelpAccessor>)accessor forKey:(NSString *)key
{
    NSLog(@"received information about value change event of key \"%@\", new value = %@", key, (NSString*)[accessor getMAFValueForKey:key]);
}

// MAFValueHelpControllerDelegate implementation

-(void)valueHelpController:(MAFValueHelpController*)controller didSelectItem:(MAFKeyValuePair*)item
{
    [controller dismissModalViewControllerAnimated:YES];
}
In addition to implementing the delegate protocols, bind the MySampleViewController to the mediator class. Set it as the delegate for the MAFValueHelpMediator factory class by introducing the mediator property:
// the factory object creating the MAF locale aware controls
@property (nonatomic, retain) MAFValueHelpMediator* mediator;
and instantiating it in an appropriate place:
// CREATE the MAF Locale Aware Controls factory
    
MAFValueHelpMediator* tempMediator = [[MAFValueHelpMediator alloc] init];
self.mediator = tempMediator;
[tempMediator release];
self.mediator.delegate = self;    // set the MAFValueHelpMediatorDelegate

To instantiate the mediator and cretate the locale-aware controls, use the createLocaleAwareControls method in the MySampleViewController class by calling it from the init method of the class, as described in Setting Up a Frame for a Sample Application.

This code creates a MAFFormatterSettings instance to read configuration that serves as input formatting information for the currency handler controls when creating them:
- (void) createLocaleAwareControls
{

    // CREATE the MAF Locale Aware Controls factory
    
    MAFValueHelpMediator* tempMediator = [[MAFValueHelpMediator alloc] init];
    self.mediator = tempMediator;
    [tempMediator release];
    self.mediator.delegate = self;    // set the MAFValueHelpMediatorDelegate
    
    // create a formatting definition for the currency number values
    MAFCurrencyFormatterSettings* formatterSettings = [[MAFCurrencyFormatterSettings alloc] initWithLength:10 andDecimalPlaces:2 andFlags:CURRENCY_FORMATTER_FLAG_SIGNED];
    
    // I. CREATE Currency Field
    
    // create the currency value cell
    MAFCurrencyTableViewCell* cellCurrency = [self.mediator getCurrencyTableViewCellWithCurrencyFormatterSetting:formatterSettings];
    
    // II. CREATE Currency Value and Selector Fields
    
    // create the currency value cell
    MAFCurrencyValueTableViewCell* cellCurrencyValue = [self.mediator getCurrencyValueTableViewCellWithCurrencyFormatterSetting:formatterSettings];
    
    // create the currency selector cell
    MAFCurrencySelectorTableViewCell* cellCurrencySelector = [self.mediator getCurrencySelectorTableViewCell];

    // release reference used for currency fields
    [formatterSettings release];
    
    // III. CREATE Phone Number Field
    
    // create the phone number cell
    MAFPhoneNumberTableViewCell* cellPhoneNumber = [self.mediator getPhoneNumberTableViewCell];
    
    // IV. CREATE Address Field
   
    // create the address cell
    MAFAddressTableViewCell* cellAddress = [self.mediator getAddressTableViewCell];


    // ADD AND STORE the cells above to self.tableViewCells
    // …

}
The above code only creates the controls; to present them later, collect the cells per controls (some of the controls, such as the currency selector and selector fields need 2 cells for its presentation) in the tableViewCells mutable array property. For example, to store the currency value cells with selector controls, add the following lines to the end of the method:
    // SECTION 2
    NSMutableArray* cellsSection2 = [NSMutableArray array];
    [cellsSection2 addObject:cellCurrencyValue];
    [cellsSection2 addObject:cellCurrencySelector];
    [self.tableViewCells addObject:cellsSection2];
Next, provide these cells via the dataSource delegate methods to the table view that presents the controls:
// data source delegate method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [(NSArray*)[self.tableViewCells objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
}

Always appropriately set the height for the cells containing the locale-aware controls, as some controls, such as the address control, can span multiple field heights. To set the height, add this implementation of heightForRowAtIndexPath in MySampleViewController:

// table view delegate method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[(NSArray*)[self.tableViewCells objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] isKindOfClass:[MAFTableViewCell class]]) {
        return ((MAFTableViewCell*)[(NSArray*)[self.tableViewCells objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]).preferredCellHeight;
    } else {
        return 10.0f;
    }
}