TestsTested | ✗ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | Jan 2018 |
SwiftSwift Version | 3.0 |
SPMSupports SPM | ✗ |
Maintained by Meniny.
Formal
is a UITableView
form builder.
You are welcome to fork and submit pull requests.
Formal
is open-sourced software, licensed under the MIT
license.
Formal
allows you to simply add sections and rows by extending FormalViewController
.
class ViewController: FormalViewController {
// ...
}
You could create a form by just setting up the Formal
property by yourself without extending from FormalViewController
.
class ViewController: UIViewController: FormalDelegate {
var formal: Formal = Formal()
override func viewDidLoad() {
super.viewDidLoad()
formal.delegate = self
}
func sectionsHaveBeenAdded(_ sections: [FormalSection], at: IndexSet) {
}
func sectionsHaveBeenRemoved(_ sections: [FormalSection], at: IndexSet) {
}
func sectionsHaveBeenReplaced(oldSections: [FormalSection], newSections: [FormalSection], at: IndexSet) {
}
func rowsHaveBeenAdded(_ rows: [FormalBaseRow], at: [IndexPath]) {
}
func rowsHaveBeenRemoved(_ rows: [FormalBaseRow], at: [IndexPath]) {
}
func rowsHaveBeenReplaced(oldRows: [FormalBaseRow], newRows: [FormalBaseRow], at: [IndexPath]) {
}
func valueHasBeenChanged(for: FormalBaseRow, oldValue: Any?, newValue: Any?) {
}
}
formal +++ FormalSection("Base")
formal +++ FormalSection(header: "Acknowledgement", footer: "https://github.com/Meniny/Formal")
formal +++ FormalSection(header: "Setup", footer: "Footer", { section in
// ...
})
formal +++ FormalSection("Base")
<<< FormalTextRow() {
$0.textType = .account
$0.title = "Account"
$0.placeholder = "Enter account here"
$0.value = "Meniny"
}
formal.removeAll()
formal.animationSettings.rowInsertAnimation = .fade
public enum FormalTextType {
case normal
case phone
case account
case password
case name
case email
case twitter
case zipCode
}
formal +++ FormalSection("Base")
<<< FormalTextRow() {
$0.textType = .account
$0.title = "Account"
$0.placeholder = "Enter account here"
$0.value = "Meniny"
}
<<< FormalTextRow() { row in
row.textType = .password
row.title = "Password"
row.placeholder = "Enter password here"
}
<<< FormalTextRow(.email, tag: "Email", { (row) in
row.title = "Email"
row.placeholder = "Enter Email here"
})
<<< FormalTextRow(.twitter, tag: "Twitter", { (row) in
row.title = "Twitter"
row.placeholder = "Twitter Text here"
})
formal +++ FormalSection("Base")
<<< FormalURLRow() { row in
row.title = "URL"
row.placeholder = "Enther URL here"
}
formal +++ FormalSection("Base")
<<< FormalTextAreaRow() { row in
row.placeholder = "TextArea"
}
formal +++ FormalSection("Base")
<<< FormalDecimalRow() { row in
row.title = "Decimal"
row.placeholder = "Enter decimal here"
}
formal +++ FormalSection("Base")
<<< FormalSwitchRow() { row in
row.title = "Switch"
row.tag = "Switch"
}
formal +++ FormalSection("Base")
<<< FormalButtonRow() { row in
row.title = "Button"
}
formal +++ FormalSection("Base")
<<< FormalLabelRow() { row in
row.title = "Label"
}
formal +++ FormalSection("Base")
<<< FormalCheckRow() { row in
row.title = "Check"
row.value = true
}.onChange({ (row) in
print("\(row.value!)")
})
<<< FormalImageCheckRow() { row in
row.title = "Image Check"
row.value = true
}
formal +++ FormalSection("Base")
<<< FormalTextFloatingFieldRow() { row in
row.placeholder = "Enter text here"
row.value = "Floating Text Field"
}
<<< FormalURLFloatingFieldRow() { row in
row.placeholder = "Enter URL here"
row.value = URL(string: "https://meniny.cn/")
}
formal +++ FormalSection("Base")
<<< FormalStepperRow() { row in
row.title = "Stepper"
row.value = 2
}
formal +++ FormalSection("Base")
<<< FormalLocationRow() { row in
row.title = "Location"
}
formal +++ FormalSection("Base")
<<< FormalGenericPasswordRow() { row in
let password = "[ABCdef123]"
row.placeholder = "Generic Password \(password)"
row.value = password
}
formal +++ FormalSection("Base")
<<< FormalSliderRow() { row in
row.title = "Slider"
}
formal +++ FormalSection("Options")
<<< FormalSegmentedRow<String>() { row in
row.title = "Segmented"
row.options = options
}
formal +++ FormalSection("Options")
<<< FormalPushSelectorRow<String>() { row in
row.title = "Push"
row.options = options
}
formal +++ FormalSection("Options")
<<< FormalPopoverSelectorRow<String>() { row in
row.title = "Popover"
row.options = options
}
formal +++ FormalSection("Options")
<<< FormalPickerInlineRow<String>() { row in
row.title = "Picker Inline"
row.options = options
}
<<< FormalDateInlineRow() { row in
row.title = "Date Inline"
}
<<< FormalPickerRow<String>() { row in
var opts = [String]()
for i in 0...5 {
opts.append("Picker \(i)")
}
row.options = opts
}
formal +++ FormalSection("Options")
<<< FormalActionSheetRow<String>() { row in
row.title = "ActionSheet"
row.options = options
}
formal +++ FormalSection("Options")
<<< FormalAlertRow<String>() { row in
row.title = "Alert"
row.options = options
}
formal +++ FormalSection("Options")
<<< FormalPickerInputRow<String>("Picker Input Row") { row in
row.title = "PickerInput"
row.options = []
for i in 1...10 {
row.options.append("PickerInput \(i)")
}
row.value = row.options.first
}
<<< FormalPhotoPickerRow() { row in
row.title = "Image"
}
Use FormalCondition
to hide/show sections and rows.
formal +++ FormalSection("Testing", { (section) in
section.tag = "TestingSection"
section.hidden = FormalCondition.closure(tags: ["HidingSwitch"], closure: { (f) -> Bool in
if let r = f.rowBy(tag: "HidingSwitch") as? FormalSwitchRow {
return r.value ?? false
}
return false
})
})
<<< FormalLabelRow() {
$0.title = "Home"
$0.value = "https://github.com/Formal"
}
formal +++ FormalSection("Hiding")
<<< FormalSwitchRow("HidingSwitch") { row in
row.title = "Hide Testings Section"
row.value = false
}
See the sample project for more detail.