Customising a table view with mySettings

I’ve been working on my iPhone app lately (for performing physical exercises like the ones you get from a physiotherapist, but more about that later) so I haven’t written anything for a long time. I thought I’d rectify that by showing how to create highly customised UIs with fairly little coding. I recently added support for delegates to mySettings and that opened up a lot of possibilities, even with only one method in the delegate (for now).

As an example, here’s the configuration screen for my app:

Configuration screen

To do this I had to, of course, install mySettings. Then create this plist:

Plist configuration file

And configure the table view:

NSString *plist = [[NSBundle mainBundle] pathForResource:@"ExerciseSettingsView" ofType:@"plist"];
tableviewdelegate = [[ExerciseSettingsTableViewDelegate alloc] initWithConfigFile:plist andSettings:exercise];
tableviewdelegate.delegate = self;
tableviewdelegate.viewcontroller = self;

tableview.backgroundColor = [UIColor clearColor];
tableview.rowHeight = 53;
tableview.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
tableview.separatorColor = [UIColor clearColor];

tableview.delegate = tableviewdelegate;
tableview.dataSource = tableviewdelegate;

“exercise” is the model object containing the values, including the array “repetitions” populating the bottom section of the table view. “ExerciseSettingsTableViewDelegate” is a subclass of “SettingsMetadataSource” from mySettings. I use it to override

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

so I can add on the alternating background images (since I need the row number for that). I also override

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

to provide the different row heights for the two sections.

The bottom section has custom cells, but the top one uses the standard cells from mySettings. To customise the fonts, colours, background view and accessory view I use the delegate function

- (void) cellDidInit:(SettingsCell *)cell

which is called right after the cell has been initialised.

The tricky bit

Sadly the difficult part is still left; the user needs to be able to add, remove and reorder the cells in the bottom section, and I have not been able to find a way to customise the reorder control. The built-in one looks completely out of place here. Not to mention the red minus sign for removing cells.

  • The ability to add remove and reorder cells has been added to mySettings. Customising the reorder control is still unsolved though, I guess I just have to live with it.

  • I have been able to bring up the settings and create a custom cell, but, but I don’t understand where to set the delegate so that the framework sends it a customCellWasSelectedAtIndexPath: message. My feeble attempt went something like this:

    NSString *plist = [[NSBundle mainBundle] pathForResource:@”Settings” ofType:@”plist”];

    SettingsViewController *controller = [[SettingsViewController alloc] initWithConfigFile:plist];

    SettingsMetadataSource *mdSource = [[SettingsMetadataSource alloc] initWithConfigFile:plist andSettings:controller.settings];

    mdSource.delegate = self;

    [self.navigationController setViewControllers:[NSArray arrayWithObject:controller] animated:NO];
    [controller release];

    • If you’re adding custom cells or behaviour it is probably easier to create your own view controller. You can always use SettingsViewController as a starting point. The SettingsViewController creates its own SettingsMetadataSource, so in the code above you end up with two SettingsMetadataSource objects that have no impact on each other.

  • Is it possible to use mysettings to also allow the user to edit settings stored in they keychain (not in the plist). I would imagine this would be performed with custom actions on some elements?

    • I don’t know, maybe you could do it with a custom cell, a subclass of one of the standard cells? Or if all the settings in the page are from the keychain you could try using the keychain as the settings object.

  • nice share, good article, very usefull for me…thanks