For a getting started guide, reference docs and included forms, head to the documentation.
Want to dive right in?
pod install 'AstroForms'
Astro Forms is a framework that provides the structure to build your own highly custom and reusable forms for a project. In this way it's different to other frameworks - it's specifically not a drop in set of subclassable elements or abstraction around UIKit. Instead, it's a set of protocols and a minimum of abstract classes you compose to build your forms. This is an opinionated way of doing things, however you'll have far less code (less 🐛s) and far more flexibility for anything but trivial stock-standard looking forms.
It's a UIView
subclass that contains a single UIStackView
- it controls rendering, show/hide, validation and all the other form like features you might need.
It's a class that conforms to various Row
protocols (ValueRow
, FocusableRow
...) so it can interact with its Form
, plus a plain old UIView
and a Nib.
For a getting started guide, reference docs and a info on the included forms, head to the documentation.
If you'd prefer to read the code, here's an example login form and text field row.
As a basic overview however to give you an idea of what it's like to use Astro Forms:
Rendering a row is as simple as giving it a tag and configuring it's view:
let emailRow = TextFieldRow(tag: LoginFormTag.email) {
$0.view.label.text = "Email"
$0.view.textField.placeholder = "example@astroforms.com"
$0.view.textField.keyboardType = .emailAddress
$0.view.textField.autocorrectionType = UITextAutocorrectionType.no
}
// inside a Form subclass
add(emailRow)
You can see the implementation for this row here.
Finding a row is easy and type safe:
let emailRow: TextFieldRow? = findRow(tag: LoginFormTag.email)
The value is typed for every row too:
let stringValue = emailRow?.value
RowTag
implementations can have associated values, so dynamic row rendering and access is easy too:
let addressLine4Row: TextFieldRow? = findRow(tag: LoginFormTag.custom("address-line-4"))
Forms can validate rows with a convenient block-chaining syntax:
let isValid: Bool = validate(
row: emailRow,
{ $0.count > 0 }, // The rows typed value (String) is passed into each validation block
{ $0.contains "@" }
)
A built in factory ValidationRule
provides validation methods that can be extended for reusability. For example, instead of the (hilariously poor) email validation above, ValidationRule.isEmail
is built in. This can be mixed with inline rules.
let isValid: Bool = validate(
row: emailRow,
{ $0.count > 0 }, // The rows typed valued is passed into each validation block
ValidationRule.isEmail
)