An open API service indexing awesome lists of open source software.

https://github.com/zoul/typed-forms

An experimental typed form library for iOS
https://github.com/zoul/typed-forms

forms swift uitableview well-typed

Last synced: about 1 year ago
JSON representation

An experimental typed form library for iOS

Awesome Lists containing this project

README

          

Tables are often used to build forms on iOS, but the `UITableView` API is fairly low-level, offering a plenty of rope to hang yourself. This library attempts to think of a better, high-level API for building type-safe(r) forms using tables.

The key idea is splitting the particular form logic into a standalone view model type that handles just the logic, and then using simple, declarative rules to build the table cells from that model:

```
//
// The view model
//

struct Card: Equatable, CustomStringConvertible {

let name: String
let currencies: [String]

var description: String {
return name
}
}

struct ViewModel {

var cards: [Card]
var selectedCard: Card {
didSet {
selectedCurrency = selectedCard.currencies.first!
}
}

var selectedCurrency: String
var specifyAmount: Bool
var amount: String?

var canBeSubmitted: Bool {
guard specifyAmount else { return true }
guard let amount = amount else { return false }
return Double(amount) != nil
}
}

//
// Sample data
//

let card1 = Card(name: "Card #1", currencies: ["CZK", "EUR"])
let card2 = Card(name: "Card #2", currencies: ["EUR", "PLN", "GBP"])
let card3 = Card(name: "Card #3", currencies: ["EUR"])
let model = ViewModel(
cards: [card1, card2, card3], selectedCard: card2,
selectedCurrency: "EUR", specifyAmount: false, amount: "1000")

//
// Now let’s build a form from that
//

let form = Form()

form += SelectableSection("Cards", items: \.cards, selectedItem: \.selectedCard)

form += Section("Currency")
<<< FormSegmentedCell(items: \.selectedCard.currencies, selectedItem: \.selectedCurrency)

form += Section()
<<< FormSwitchCell(keyPath: \.specifyAmount, title: "Specify Amount")
<<< FormTextFieldCell(keyPath: \.amount) {
$0.textField.placeholder = "Enter amount"
$0.textField.clearButtonMode = .whileEditing
$0.bind(\.isHidden, to: \.specifyAmount, through: { !$0 })
}

form += Section()
<<< FormButtonCell(title: "Pay") {
$0.bind(\.shouldHighlight, to: \.canBeSubmitted)
}
}
```

The `form` object can then be used as a table view data source. The table form is always in sync with the model, there’s no need to manually update the table after model changes or vice versa.

## Related Work / Inspiration

* [Eureka](https://github.com/xmartlabs/Eureka/), a full-featured form building library. Very powerful, but unfortunately not very type safe.
* [Swift Talks: Building a Form Library](https://talk.objc.io/collections/building-a-form-library), great ideas about building modern, type-safe form library.