Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/neoneye/SwiftyFORM

iOS framework for creating forms
https://github.com/neoneye/SwiftyFORM

binding form ios swift uidatepicker uipickerview uislider uitableview validation

Last synced: 22 days ago
JSON representation

iOS framework for creating forms

Awesome Lists containing this project

README

        



SwiftyFORM by Simon Strandgaard


SwiftyFORM

---



Build Status


Version


Platform


Swift Package Manager


Carthage


MIT License


SwiftyFORM is a lightweight iOS framework for creating forms


Dark Mode supported

Because form code is hard to write, hard to read, hard to reason about. Has a slow turn around time. Is painful to maintain.

[SwiftyFORM demo on YouTube](https://youtu.be/PKbVJ91uQdA)


## Requirements

- iOS 12+
- Xcode 12+
- Swift 5.1+

## Features

- [x] Several form items, such as textfield, buttons, sliders
- [x] Some form items can expand/collapse, such as datepicker, pickerview
- [x] You can create your own custom form items
- [x] Align textfields across multiple rows
- [x] Form validation rule engine
- [x] Shows with red text where there are problems with validation
- [x] Strongly Typed
- [x] Pure Swift
- [x] No 3rd party dependencies

# USAGE

### Tutorial 0 - Static text

```swift
import SwiftyFORM
class MyViewController: FormViewController {
override func populate(_ builder: FormBuilder) {
builder += StaticTextFormItem().title("Hello").value("World")
}
}
```

### Tutorial 1 - TextField

```swift
import SwiftyFORM
class MyViewController: FormViewController {
override func populate(_ builder: FormBuilder) {
builder += TextFieldFormItem().title("Email").placeholder("Please specify").keyboardType(.emailAddress)
}
}
```

### Tutorial 2 - Open child view controller

```swift
import SwiftyFORM
class MyViewController: FormViewController {
override func populate(_ builder: FormBuilder) {
builder += ViewControllerFormItem().title("Go to view controller").viewController(FirstViewController.self)
}
}
```

### Advanced - date picker

```swift
class DatePickerBindingViewController: FormViewController {
override func populate(_ builder: FormBuilder) {
builder += datePicker
builder += incrementButton
builder += decrementButton
builder += SectionFormItem()
builder += summary
updateSummary()
}

lazy var datePicker: DatePickerFormItem = {
let instance = DatePickerFormItem()
instance.title = "Date"
instance.datePickerMode = .date
instance.behavior = .expandedAlways
instance.valueDidChangeBlock = { [weak self] _ in
self?.updateSummary()
}
return instance
}()

lazy var incrementButton: ButtonFormItem = {
let instance = ButtonFormItem()
instance.title = "Next Day"
instance.action = { [weak self] in
self?.increment()
}
return instance
}()

lazy var decrementButton: ButtonFormItem = {
let instance = ButtonFormItem()
instance.title = "Previous Day"
instance.action = { [weak self] in
self?.decrement()
}
return instance
}()

lazy var summary: StaticTextFormItem = {
return StaticTextFormItem().title("Date").value("-")
}()

func updateSummary() {
summary.value = "\(datePicker.value)"
}

func offsetDate(_ date: Date, days: Int) -> Date {
var dateComponents = DateComponents()
dateComponents.day = days
let calendar = Calendar.current
guard let resultDate = calendar.date(byAdding: dateComponents, to: date) else {
return date
}
return resultDate
}

func increment() {
datePicker.setValue(offsetDate(datePicker.value, days: 1), animated: true)
updateSummary()
}

func decrement() {
datePicker.setValue(offsetDate(datePicker.value, days: -1), animated: true)
updateSummary()
}
}
```

### Advanced - Validation

![Change password form](https://github.com/neoneye/SwiftyFORM/raw/master/Documentation/change_password_form.gif "Change password form")

```swift
class ChangePasswordViewController: FormViewController {
override func populate(_ builder: FormBuilder) {
builder.navigationTitle = "Password"
builder += SectionHeaderTitleFormItem().title("Your Old Password")
builder += passwordOld
builder += SectionHeaderTitleFormItem().title("Your New Password")
builder += passwordNew
builder += passwordNewRepeated
builder.alignLeft([passwordOld, passwordNew, passwordNewRepeated])
}

lazy var passwordOld: TextFieldFormItem = {
let instance = TextFieldFormItem()
instance.title("Old password").password().placeholder("required")
instance.keyboardType = .numberPad
instance.autocorrectionType = .no
instance.validate(CharacterSetSpecification.decimalDigitCharacterSet(), message: "Must be digits")
instance.submitValidate(CountSpecification.min(4), message: "Length must be minimum 4 digits")
instance.validate(CountSpecification.max(6), message: "Length must be maximum 6 digits")
return instance
}()

lazy var passwordNew: TextFieldFormItem = {
let instance = TextFieldFormItem()
instance.title("New password").password().placeholder("required")
instance.keyboardType = .numberPad
instance.autocorrectionType = .no
instance.validate(CharacterSetSpecification.decimalDigitCharacterSet(), message: "Must be digits")
instance.submitValidate(CountSpecification.min(4), message: "Length must be minimum 4 digits")
instance.validate(CountSpecification.max(6), message: "Length must be maximum 6 digits")
return instance
}()

lazy var passwordNewRepeated: TextFieldFormItem = {
let instance = TextFieldFormItem()
instance.title("Repeat password").password().placeholder("required")
instance.keyboardType = .numberPad
instance.autocorrectionType = .no
instance.validate(CharacterSetSpecification.decimalDigitCharacterSet(), message: "Must be digits")
instance.submitValidate(CountSpecification.min(4), message: "Length must be minimum 4 digits")
instance.validate(CountSpecification.max(6), message: "Length must be maximum 6 digits")
return instance
}()
}
```

# INSTALLATION

## Swift Package Manager

With Swift Package Manager support in the latest Xcode, installation has never been easier.

Open your Xcode project -> `File` -> `Swift Packages` -> `Add Package Dependency...`

Search for `SwiftyFORM` and specify the version you want. The latest tagged release is usually a good idea.

## CocoaPods

To integrate SwiftyFORM into your Xcode project using CocoaPods, specify the following in your `Podfile`:

```ruby
source 'https://github.com/CocoaPods/Specs.git'
swift_version = '5.0'
platform :ios, '12.0'
use_frameworks!

target 'MyApp' do
pod 'SwiftyFORM', '~> 1.8'
end
```

Then, run the following command:

```bash
$ pod install
```

## Carthage

[Link to demo project that shows a minimal SwiftyFORM app using Carthage](https://github.com/neoneye/SwiftyFORM-Carthage-Example).

To integrate SwiftyFORM into your Xcode project using Carthage, specify it in your `Cartfile`:
```
github "neoneye/SwiftyFORM" ~> 1.8
```

Then, run the following command:
```bash
$ carthage update
```

Finally, add `SwiftyFORM.framework` (will be built by Carthage under `Carthage/Build/iOS/`) to your project's _Linked Frameworks and Libraries_ in the _General_ tab, and add a new _Run Script_ Build Phase:
- Set `/bin/bash` as the shell
- write `/usr/local/bin/carthage copy-frameworks` in the script body
- add `$(SRCROOT)/Carthage/Build/iOS/SwiftyFORM.framework` to the input files

## Manual

1. Open up Terminal application and cd into your iOS project directory

2. ONLY IF your project is not already initialized as a git repository, run
```
$ git init
```

3. Add `SwiftyFORM` as a submodule by running
```
$ git submodule add https://github.com/neoneye/SwiftyFORM.git
```

4. In the Project Navigator, select your application project and go to "Targets" -> "General"

5. Open the project folder and drag the `SwiftyFORM.xcodeproj` file into the "Frameworks, Libraries, and Embedded Content" tab of your application.

6. Click the `+` button under the "Frameworks, Libraries, and Embedded Content" section and `Add` the `SwiftyFORM.framework`

# Communication

- If you want to contribute, submit a pull request.
- If you found a bug, have suggestions or need help, please, open an issue.
- If you need help, write me: [email protected]