SDForms

SDForms is an Objective-C library that makes creating table view-based forms easier and faster on iOS. It was developed as a side effect of one of our project and it implements all the code responsible for managing table view cells, their sizes, dynamic number of rows etc. The core of the library is the SDForm class. User has only to create its instance and set its data source and delegate, which implement methods similar to UITableViewDelegate and UITableViewDataSource. The difference is that instead of UITableViewCells, user operates on classes inheriting from SDFormField class. Form fields in their implementations register cell classes or nibs in UITableView and pass the cells to the form. Fields also implement a mechanism of connecting Objective-C objects with the fields. It’s helpful in mapping values of fields directly to objects’ properties and vice versa.

Basic usage

In order to use SDForms in view controller that has a UITableView, you have to initialize an SDForm object and pass the table view to it:

  

Then it’s important to implement data source methods:

  

These three methods are mandatory. There are also other optional methods where you can specify section headers appearance. Now let’s get to defining fields:

  

That’s all we have to do to generate nicely looking form with three fields:

Basic form

The picker below date field appears after you tap on the field and disappears if you tap it again

Field types

Below there are described predefined types of fields that are delivered with a library.

SDTextFormField

Basic field that contains text field allowing user to edit values. You can specify its autocorrection and autocapitalization style, and if it has to contain secured data. Specifying its valueType property lets you define what keyboard will be displayed to the user. You can see the usage and the appearence of the field in the previous paragraph.

SDMultilineTextField

Field that displays cells containing an UITextView component. You can specify its text params, placeholder, and if the text view is supposed to be editable, selectable, etc. If the text view is not editable, you can specify that the height of the field is to be calculated automatically based on the text length.

  

SDMultilineTextField

SDMultilineTextField

SDLabelField

Not editable field that contains only label with specified value. You can set if it has to be displayed as title-value cell or with value only.

SDDatePickerField

Field that allows user to choose date from UIDatePicker. It was presented in the previous paragraph.

SDPickerField

It’s the most complex of predefined fields. After tapping it the UIPicker component is displayed below. You can specify the options for all of the picker components, as well as values corresponding to them (for example identifiers of objects corresponding to options).

  

SDPickerField with expanded picker view

SDPickerField with expanded picker view

SDItemSelectionField

Lets user display a view controller with a list of options that can be selected. It allows both single and multi selection. Items picker can be pushed on navigation controller stack or displayed modally. When the field is tapped, the view controller is informed by SDForm object with its delegate method that picker has to be displayed.

  

SDItemSelectionField

SDItemSelectionField

SDItemSelectionField options picker

SDItemSelectionField options picker

SDSwitchField

A field that can be used for setting typical bool value.

  

SDSwitchField

SDSwitchField

SDSliderField

A field that allows you to select a number from a specified range with defined step.

  

SDSliderField

SDSliderField

SDButtonField

A field that producess cell with text centered horizontally, that can be used as a button.

  

SDSubmitField

SDSubmitField

Other features

Reacting to tapping on fields

There are three ways of reacting to tapping on field.

  • Implementing proper SDFormDelegate method:
  
  • Setting a block that should be executed, when user taps the field:
  
  • Only for storyboards – setting the identifier of the Segue that is supposed to be performed, when user taps the field
  

Mapping field’s value to object property

In order to map field’s value to objects property, you only have to set the field’s properties “relatedObject” and “relatedPropertyKey”.

  

When you set these properties, object’s property value is set as field’s value. Now when you edit the field, for example change the text in the text field, the new value will be automatically mapped to object’s property.

Adding and removing fields and sections

In SDForms it can be done in similar way to UITableView:

  

Adding custom fields

You can easily create custom fields that match your project requirements. Let’s create some new field that displays a photo that user selects from his library.

In the beginning we should create a cell that will display a photo. Let’s call it SDPhotoCell. We create a xib file which looks like this:

Zrzut ekranu 2015-01-28 o 10.13.47

Class interface should look like this:

  

The cell should inherit from SDFormCell class. We define a static variable with reuse identifier of the cell. The same identifier should be set in the xib file. The implementation of the class is empty.

Now a field class needs to be created and it has to inherit from SDFormField class. We don’t have to add any custom fields in the interface. The implementation is described below:

  

In the reuseIdentifiers method we return an array of reuse identifiers of cells that the field uses. Our field consists of only one cell, so we return only one element in the array. The only situation when a field can consist of more than one field is when you display a picker that should appear when user taps the field – then we should return a second identifier for the picker field. Similarly, in cellHeights method we return an array of heights of cells used by the field.

CellForTableView:atIndex: method is a place where you can set your cells’ properties. We assume that the field in its value property will keep an object of UIImage class. If it’s nil, we display a placeholder label. Otherwise, we display an image.

Now it’s time to implement the field’s behaviour. In form:didSelectFieldAtIndex: method we can put a code that will be executed, when user taps the field on the cell with relative index that is passed as a second parameter. Speaking relative, I mean that the first cell of the field would have its index equal 0, the second – 1 and so on. For our field we just display an UIIMagePickerController that will allow user to select a photo from the library. The field has a method presentViewController:animated: that tells the view controller displaying the form (using chain of delegates) to present other view controller.

Finally, we just set the image returned by the UIImagePickerController to the value property of the field. Simple, isn’t it?

To use our new field we just have to write a little piece of code:

  

Then we can return it in the form:fieldForRow:inSection: method. One detail: presentingMode property of the field tells the field how it should present it’s related view controller – we can do it modally or push it on navigation controller’s stack.

That’s all, now we can freely use our new field in the application:

Just tap on the cell

Just tap on the cell

Select the photo

Select the photo

Photo is displayed in the form

The photo is displayed in the form

GitHub

Our library is available on GitHub, so if you are interested in its evolution, you can track it on: https://github.com/SnowdogApps/SDForms. If you have any questions or suggestions about it, feel free to share it with us in comments below!