views:

164

answers:

1

Hi,

I want to design an app that needs user to input few things like start date, end date, bunch of other options and some text comments for which I am planning to use pickers to select the data that will slide up modally. I will need to move the view up and down to make sure that the element being filled stays in focus when the pickers and keyboard slides up and down.

My question is what would be the best view to implement such a "form"? I was thinking grouped table view where I could separate the fields section wise.

Is there any other way to implement these things? By experience or best practices, are there any better alternatives or sample code or apps out there that I can explore?

Dev.

+5  A: 

The most iPhone-like interface for forms is going to be a grouped table view. It is what most users will expect, after using other apps which use grouped table views for adding and editing structured data.

A good practice is to create an enum (enumeration) for sections and for rows within sections, e.g.:

typedef enum {
    kFormSectionFirstSection = 0,
    kFormSectionSecondSection,
    kFormSectionThirdSection,
    kFormSections
} FormSection;

typedef enum {
    kFormFirstSectionFirstRow = 0,
    kFormFirstSectionSecondRow,
    kFormFirstSectionRows
} FormFirstSectionRow;

...

In this example, you can use this enumeration to refer to sections by name instead of number.

(In practice, you probably wouldn't use kFormSectionFirstSection as a descriptive name, but something like kFormSectionNameFieldSection or kFormSectionAddressFieldSection etc., but this should hopefully illustrate the structure of the enum.)

How would you use this?

Here's an example of a few table view delegate methods which demonstrate how this is useful:

- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return kFormSections;
}

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    switch (section) {
        case kFormSectionFirstSection:
            return kFormFirstSectionRows;

        case kFormSectionSectionSection:
            return kFormSecondSectionRows;

        ...

        default:
            break;
    }
    return -1;
}

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

    // cell setup or dequeue...

    switch (indexPath.section) {
        case kFormSectionThirdSection: { 
            switch (indexPath.row) {
                case kFormThirdSectionFourthRow: {

                    // do something special here with configuring 
                    // the cell in the third section and fourth row...

                    break;
                }

                default:
                    break;
            }
        }

        default:
            break;
    }

    return cell;
}

This should quickly show the utility and power of enumerations.

Names in code are much easier to read than numbers. When you're dealing with delegate methods, if you have a good descriptive name for a section or a row, you can more easily read the logic of how the table view and cells are managed.

If you want to change the order of sections or row, all you have to do is rearrange the order of enumerated labels in the enum construct. You wouldn't need to go into all the delegate methods and change magic numbers, which quickly becomes a tricky and error-prone dance once you have more than a couple sections and rows.

Alex Reynolds
Great explination. I would also point out that with using a UITableView you can call `- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:` on the tableView to scroll the current field so it is in optimal position while the keyboard is shown.
jamone
Awesome! Thanks @Alex and @jamone
Dev