frankodwyer / FODFormKit

A library for creating dynamic forms for iOS.
MIT License
49 stars 2 forks source link

FODFormKit

Note: I'm no longer actively maintaining this. If you are looking for a form library meanwhile, I suggest Eureka

Build Status

Usage

FODFormKit is a library for creating dynamic forms for iOS.

To run the example project; clone the repo, and run pod install from the Project directory first.

For details of how to use the library in your own project, see Creating Forms below.

Screeenshots

Form with subform:

 

Inline (expandable) subform:

   

Inline (expandable) editors

 

Textfield navigation:

 

Requirements

FODFormKit currently requires iOS7. It mostly works on iOS6 with cosmetic issues, but I don't have a need for this currently so I'm unlikely to fix them myself. Pull requests with iOS6 fixes are welcome, though.

Installation

FODFormKit is available through CocoaPods, to install it simply add the following line to your Podfile:

pod "FODFormKit"

Creating Forms

Creating forms programmatically

You can create forms programmatically using a FODFormBuilder object. See the demo project (FODViewController.m) for more examples.

FODFormBuilder *builder = [[FODFormBuilder alloc] init];

[builder startFormWithTitle:@"Main Form"];

[builder section:@"Section 1"];

[builder selectionRowWithKey:@"picker"
                    andTitle:@"Select a wibble"
                    andValue:nil
                    andItems:@[@"wibble1", @"wibble2", @"wibble3"]];

[builder selectionRowWithKey:@"picker2"
                    andTitle:@"Select a fooby"
                    andValue:nil
                    andItems:@[@"fooby1", @"fooby2", @"fooby3"]].displayInline = YES;

[builder section];

[builder rowWithKey:@"date2"
            ofClass:[FODDateSelectionRow class]
           andTitle:@"When"
           andValue:nil];
[builder rowWithKey:@"date1"
            ofClass:[FODDateSelectionRow class]
           andTitle:@"When Inline"
           andValue:nil].displayInline = YES;

FODForm *form = [builder finishForm];

The builder object automatically keeps track of nested subforms and wires them up appropriately to their parent forms.

Each call to the builder object returns the form, row, or section that was just created. To have a form or row display inline if possible (using expanding/collapsing cells), add .displayInline = YES;. (Currently only subforms, and rows of type FODSelectionRow or FODDateSelectionRow support this option.)

Each row must have a unique key within its form (and, in the case of inline subforms, the key must be unique within the parent form also). The key is used to retrieve the form values after a form has been completed.

Creating forms from a plist

You can get the plist representation of a form by building it programmatically and calling form.toPlist. This format can then be written to a file in order to get a template that you can edit. For example, you can do this kind of thing in the debugger:

(lldb) po [form.toPlist writeToFile:@"/Users/frank/form2.plist" atomically:YES]

To load a form from a plist, use:

id plist = // load the plist from somewhere, e.g. a file or resource
FODForm *form = [FODForm fromPlist:plist];

Using a form

To display a form and allow a user to complete it:

FODFormViewController *vc = [[FODFormViewController alloc] initWithForm:form userInfo:nil];
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];

To retrieve the values that a user filled in, and to handle cancellation, implement the form delegate methods:

- (void)formSaved:(FODForm *)model
         userInfo:(id)userInfo {
    NSString *value1 = (NSString*)[model valueForKeyPath:@"somekey"];
    NSString *value2 = (NSString*)[model valueForKeyPath:@"subform.somekey"];
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)formCancelled:(FODForm *)model
             userInfo:(id)userInfo {
    [self.navigationController popViewControllerAnimated:YES];
}

Customisation

The library does not support much customisation yet, however many aspects can be tailored by subclassing FODCellFactory to return different cells for different row types. (For example, subclasses of the existing cells, or a new subclass of FODFormCell)

You can also add entirely new row types by adding subclasses of FODFormRow, adding a subclass of FODFormCell to represent it, and then extending FODFormBuilder and FODCellFactory to support the new row and cell types.

To add new kinds of inline editable cells, you can subclass FODInlineEditorCell and provide a view controller that edits your row type. Given overrides for the following methods, the superclass will manage containment of your view controller.

- (UIViewController*)createEditorController;
- (CGFloat) heightForEditorController:(CGFloat)maxHeight;

See FODInlinePickerCell or FODInlineDatePickerCell for examples of this.

(If you add a subclass or new row type, feel free to send a pull request)

Caveats

Author

Frank O'Dwyer

License

FODFormKit is available under the MIT license. See the LICENSE file for more info.

Bitdeli Badge