Upload
john-pham
View
230
Download
1
Embed Size (px)
Citation preview
Eureka - Elegant iOS form builder in Swift
JohnP - Mingle
What makes Eureka so special?
1. Elegant, concise syntax and super readable
2. Support dynamic table-view forms
3. Fully customizable4. Safe5. Powerful and Flexible6. Extensible
Elegant, concise syntax and super readable
Eureka uses a chainable approach along with custom swift operators to declare a table-view form.
self.form +++= DateRow("Date") {
$0.value = NSDate()
$0.title = "The clock says:"
}
<<< CheckRow("Check") {
$0.title = "Check"
$0.value = true
}
+++ SegmentedRow<Emoji>("SegmentedRow") {
$0.title = "Who are You?"
$0.options = [ , �, , , , ]
$0.value = �
}
<<< PhoneRow("Phone") { $0.placeholder = "Phone" }
Support dynamic table-view forms
Eureka provides a very powerful DSL used to create a form, basically a form is represented by a Form instance that contains Sections which finally contain Rows.
Typically any form we might build needs to make a row or section visible/invisible depending on a certain condition or action
Eureka keeps track of any change made on the Form and updates the FormViewController table view accordingly and on the fly
Fully customizable
General customization
General customization allows us to make changes to all rows or cells of a specific type.
// set up minimumDate for all DateRows
DateRow.defaultRowInitializer = { row in row.minimumDate = NSDate() }
// modify all NameRow cell textField font to
UIFont.systemFontOfSize(fontSize: 12.0)
NameRow.defaultCellUpdate = { cell, row in cell.textField?.font =
UIFont.systemFontOfSize(fontSize: 12.0) }
// Modify all CheckRow cells in order to show a orange check mark.
CheckRow.defaultCellSetup = { cell, row in cell.tintColor =
UIColor.orangeColor() }
Fully customizable
Individual customization
Individual customization allows us to make changes to a particular row or cell instance.
// Every row has a initializer that receive a tag and a initializer blog
// as a first and second parameter respectively.
let segmentedRow = SegmentedRow<Emoji>("Emoji"){
$0.title = "Who are You?" // set up the row title
$0.options = [ , �, , , , ] // available options
$0.value = � // selected value
$0.isDisabled = true // disable the row by default
}
// Every Row has a cellSetup and cellUpdate method that receive a function as a parameter and
// return the concrete row instance.
let nameRow = NameRow("Name").cellSetup { cell, row in
cell.textField.placeholder = "Your name ..."
}
.cellUpdate { cell, row in
cell.textLabel?.textColor = UIColor.redColor()
}
Safe Eureka uses Swift’s type safety to help avoiding mistakes while developing. Each Eureka Row allocates a strongly typed value and any form definition and configuration is made over specific concrete object types.
Additionally Eureka makes sure that each new user defined Row has a specific value type and a specific TableViewCell type, this is possible combining Swift Generics and Type Constraints. By definition any Row must extend from Row<T: Equatable, Cell: CellType where Cell: BaseCell, Cell.Value == T> class ensuring that each Row has a defined value type T and works with a specific table view cell Cell which holds a row of type T.
Powerful and Flexible
Eureka allows us to easily attach onChange and onSelect handlers to a row.
let segmentedRow = SegmentedRow<Emoji>("Emoji"){
$0.title = "Who are You?"
// set up the row title
$0.options = [ , �, , ,
, ] // available options
}
.onChange { row in
print(row.value?.name) } // row.value is Emoji?,
name is a stored property
.onCellSelection { cell, row
in print("Cell was selected") }
Powerful and Flexible
Form and Section conform to RangeReplaceableCollectionType, MutableCollectionType
As mentioned before, Eureka Forms contain a list of Sections and a section contains a list of Rows. It made Form and Section conform to RangeReplaceableCollectionType and MutableCollectionType, which both “inherit” from the well known CollectionType protocol.
Powerful and Flexible
// let's get second form section and append a new DateRow
let section_two = form[1] <<< DateRow("Date") { $0.value = NSDate() } // we
can also use append instead of <<< operator
// What about replacing section two?
form[1] = newSection // ;)
// lets add a new button row to all sections
for (index, section) in form.enumerate() {
section <<< ButtonRow("Button\(index)") { $0.title = "Some title" }
}
// replace rows from 3 to 7 with a checkRow
section_two.replaceRange(3..<7, with: [CheckRow("checkRow")])
// we can also look up for CheckRows inside a section by..
section_two.filter { $0 is CheckRow }
// one more example
form += [newSection1, newSection2]
section += [newRow1, newRow2, newRow3]
//And there are much more possibilities ;)
Extensible Adding a new Row definition is super simple by extending Row<T, Cell> and conforming to RowType. The basic behaviour of the row is inherited either from the superclass or added through protocol extension. Based on that you should only provide the row definition and the UITableViewCell that the Row handles. Eureka provides many rows by default that actually have no conceptual difference from a user defined row.
Community support
- > 4k github star- 55 contributors- > 750 github issue ( 90% is resolved)
Demo
Git repo: https://github.com/xmartlabs/Eureka/
1. Create basic form2. Add new custom field: Check field, static
data, Float label row...3. Form Validations
And The End…