An Effective Way to Develop and Manage iPhone Applications Similar to Settings

I just wanted to make it clear that by "design" I mean software design, not user interface design.

I have an application similar to my own settings application. The problem I am facing is that it does not match the same MVC style. Other applications tend to focus around displaying one kind of thing. For example, in the case of an application with a table table, these are elements. Elements explicitly contain a model, and they have similar properties and behavior, that is, they can be displayed and interact in the same way. An application like this almost designs itself!

My application, like the settings application, consists of an arbitrary selection of rows displaying dissimilar data in different ways. One line may contain a switch, and the other may have a very specific look when clicked. They are all very different.

How do you create something like this?

Currently, I am doing all this in the view controller, and the corresponding lines are tracked through an enumeration:

enum { kNameRow, kGenderRow, kJobTypeRow, kLevelOfExerciseRow, kEmailAddressRow, kTelephoneNumberRow }; 

As I described, these cells are all very different, so the cells are displayed as follows:

 // - tableView:cellForRowAtIndexPath pseudocode. switch (indexPath.row) { case kNameRow: // create name cell. case kGenderRow: // create gender cell. case kJobTypeRow: // create job type cell. case kLevelOfExerciseRow: // create level of exercise cell. case kEmailAddressRow: // create email address cell. case kTelephoneNumberRow: // create telephone number cell. } 

And the interaction with the cells is handled similarly:

 // - tableView:didSelectRowAtIndexPath pseudocode. switch (indexPath.row) { case kNameRow: // do name-specific stuff. case kGenderRow: // do gender-specific stuff. case kJobTypeRow: // do job type-specific stuff. case kLevelOfExerciseRow: // do level of exercise-specific stuff. case kEmailAddressRow: // do email address-specific stuff. case kTelephoneNumberRow: // do telephone number-specific stuff. } 

This seems very cumbersome, and the problem of inoperability is added when the table is divided into several sections.

Is there a better way to do this? Are there any design patterns that I would use when working with large tables of largely unrelated data?

Any advice is generally greatly appreciated.

+4
source share
4 answers

I became interested in implementing partition controllers that pull logic out of your subclass of UITableViewController (or another host controller) and move them into separate classes.

I finished the implementation of the basic protocol, which determines what the section controller should do - for me this includes the number of rows in the section and the cell for the row (the whole index path is not necessary, since the controller deals with one section). I have an extra method to return the section name and line height. This is all that I have implemented so far, since all that I really need.

This works for me because my individual sections tend to be homogeneous, but you can easily use the idea of โ€‹โ€‹returning heterogeneous cells within a single section or reorganize the idea of โ€‹โ€‹having cell type controllers instead of section controllers. In the end, my UITableViewDelegate and UITableViewDataSource methods just have to figure out which section controller to call instead of the built-in logic in the UITableViewController subclass.

I think I got the idea from in this article , but I also saw a later article that describes the same idea.

+2
source

you can see the coreyfloyds project http://github.com/coreyfloyd/Generic-Heterogeneous-Table-Views I think this may have the features you need.

+2
source

Here my suggestion is to treat each cell as a presentation item.

lol, it's been a while since I used the table, so I could just talk to him, but give it a try.

instead of using an enumeration:

 NSThingyCell *nameRow; NSThingyCell *genderRow; @property IBOutlet NSThingyCell *nameRow; @property IBOutlet NSThingyCell *genderRow; - (IBAction) nameRowChanged:(id)sender; - (IBAction) genderRowChanged:(id)sender; 

and then, instead of invoking the table using the switch, simply connect each individual cell in Interface Builder.

This added the benefits of string independence, so if you need to put an "ageRow" between the name and gender, nothing gets screwed.

It will also be quite large, so if your view has several tables, you might want to split these tables into separate nibs / controllers and load the views at runtime.

+2
source

Have you ever thought of a simple array of objects for a class that contains a user interface element and some other identifiable data?

 @interface settingsOption { NSString *key; UIView *displayElement; } + (settingsOption *)optionWithKey:(NSString *)key andDisplayElement:(UIView *)displayElement; @property (nonatomic, retain) UIView *displayElement; @property (nonatomic, retain) NSString *key; @end 

If the class method looks like

 + (settingsOption *)optionWithKey:(NSString *)key andDisplayElement:(UIView *)displayElement; settingsOption *option = [[settingsOption alloc] init]; option.key = key; option.displayElement = displayElement; return [option autorelease]; } 

Your settings class will have an array of settings. Service instances.

 - (void)somewhereInMySettingsClass mySettings = [[NSMutableArray alloc] init]; [mySettings addObject:[settingsOption optionWithKey:@"age" andDisplayElement:[UIButton buttonWithStyle:UIButtonStyleRect]]]; [mySettings addObject:...]; } 

The cellForRowAtIndexPath table will simply do

 [cell addSubview:[[mySettings objectAtIndex:indexPath.row] displayElement]]; 

However, you talked about sections that would add another layer to the data. It could just be dividing mySettings into an array of arrays instead, where each array in the array is one section.

Not sure if I missed something above. Feel free to point and poke.

You can simplify the settingsOption class by adding additional helper classes for various element types, for example.

 + (settingsOption *)buttonWithKey:(NSString *)key; + (settingsOption *)switchWithKey:(NSString *)key; + (settingsOption *)pickerWithKey:(NSString *)key withDataSource:(id <UIPickerViewDataSource>)source withDelegate:(id <UIPickerViewDelegate>)delegate; 

etc.

+2
source

All Articles