Awesome Open Source
Awesome Open Source

Flix: iOS form builder in Swift

Travis CI CocoaPods compatible Carthage compatible 中文 README

Flix is a flexible iOS framework for creating dynamic forms with UITableView or UICollectionView.


  • [x] Supports no reused when you need.
  • [x] Supports reused for list when you need.
  • [x] Supports nested forms.
  • [x] Supports add, delete and insert
  • [x] Supports Storyboard design
  • [x] Example app available!
  • [x] Works with UITableView and UICollectionView

Flix focus on combining cells of UICollectionView or UITableView, it don't care about the view layout, business logic. So you can easily build custom form using Flix.



  • Xcode 10.2+
  • Swift 5+
  • RxSwift 5.0+
  • RxDataSources 4.0+



pod 'Flix', '~> 4.0'


Each provider will generate a number of nodes (cells), then combines those providers according to the sequence.

Tutorial - A Simple Settings Page

When creating a settings page, we don't want to some cells be reused, for example Profile Cell, Airplane Mode Cell. This looks like creating a static tableView on Storyboard.

To create one profile cell, we just need to create a UniqueCustomTableViewProvider and configure the style and add some views:

let profileProvider = UniqueCustomTableViewProvider()
profileProvider.itemHeight = { _ in return 80 }
profileProvider.accessoryType = .disclosureIndicator

let avatarImageView = UIImageView( image: #imageLiteral(resourceName: "Flix Icon") ) profileProvider.contentView.addSubview(avatarImageView)

let nameLabel = UILabel() nameLabel.text = "Flix" profileProvider.contentView.addSubview(nameLabel)

let subTitleLabel = UILabel() subTitleLabel.text = "Apple ID, iCloud, iTunes & App Store" profileProvider.contentView.addSubview(subTitleLabel)[profileProvider])

Now, we have a profile cell for the settings page, considering we might use this provider on another UITableView. We should make a Class for profileProvider.

We can inherit from UniqueCustomTableViewProvider:

class ProfileProvider: UniqueCustomTableViewProvider {

    let avatarImageView = UIImageView()
    let nameLabel = UILabel()
    let subTitleLabel = UILabel()

    init(avatar: UIImage, name: String) {

        self.itemHeight = { _ in return 80 }
        self.accessoryType = .disclosureIndicator

        avatarImageView.image = avatar

        nameLabel.text = name

        subTitleLabel.text = "Apple ID, iCloud, iTunes & App Store"


or just implement the protocol UniqueAnimatableTableViewProvider:

class ProfileProvider: UniqueAnimatableTableViewProvider {

    let avatarImageView = UIImageView()
    let nameLabel = UILabel()
    let subTitleLabel = UILabel()

    init(avatar: UIImage, name: String) {
        avatarImageView.image = avatar
        nameLabel.text = name
        subTitleLabel.text = "Apple ID, iCloud, iTunes & App Store"

    func onCreate(_ tableView: UITableView, cell: UITableViewCell, indexPath: IndexPath) {
        cell.accessoryType = .disclosureIndicator

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath, value: ProfileProvider) -> CGFloat? {
        return 80


But in reality, the profile cell is placed in a section. We can use SectionProfiler:

let profileSectionProvider = SpacingSectionProvider(
    providers: [profileProvider],
    headerHeight: 35,
    footerHeight: 0

Then add more providers:

let profileProvider = ProfileProvider(
    avatar: #imageLiteral(resourceName: "Flix Icon"),
    name: "Flix")
let profileSectionProvider = SpacingSectionProvider(
    providers: [profileProvider],
    headerHeight: 35,
    footerHeight: 0)
let airplaneModeProvider = SwitchTableViewCellProvider(
    title: "Airplane Mode",
    icon: #imageLiteral(resourceName: "Airplane"),
    isOn: false)
let wifiProvider = DescriptionTableViewCellProvider(
    title: "Wi-Fi",
    icon: #imageLiteral(resourceName: "Wifi"),
    description: "Flix_5G")
let bluetoothProvider = DescriptionTableViewCellProvider(
    title: "Bluetooth",
    icon: #imageLiteral(resourceName: "Bluetooth"),
    description: "On")
let cellularProvider = DescriptionTableViewCellProvider(
    title: "Cellular",
    icon: #imageLiteral(resourceName: "Cellular"))
let hotspotProvider = DescriptionTableViewCellProvider(
    title: "Personal Hotspot",
    icon: #imageLiteral(resourceName: "Personal Hotspot"),
    description: "Off")
let carrierProvider = DescriptionTableViewCellProvider(
    title: "Carrier",
    icon: #imageLiteral(resourceName: "Carrier"),
    description: "AT&T")
let networkSectionProvider = SpacingSectionProvider(
    providers: [
    headerHeight: 35,
    footerHeight: 0
    [profileSectionProvider, networkSectionProvider]

Until now, we just use one provider to generate one cell. We can also create a provider for a group of cells.

let appSectionProvider = SpacingSectionProvider(
    providers: [AppsProvider(apps: [
        App(icon: Wallet, title: "Wallet"),
        App(icon: iTunes, title: "iTunes"),
        App(icon: Music, title: "Music"),
        App(icon: Safari, title: "Safari"),
        App(icon: News, title: "News"),
        App(icon: Camera, title: "Camera"),
        App(icon: Photos), title: "Photo")
    headerHeight: 35,
    footerHeight: 35

Look like good.

Actually Flix supports more build list view function, you can easily create a page with all kinds of linkage effects (such as Calendar Events, GitHub Signup). More example are available in the Example Folder.


  1. Please fork this project
  2. Implement new methods or changes。
  3. Write appropriate docs and comments in the
  4. Submit a pull request.


Raise an Issue or hit me up on Twitter @Songxut.


Flix is released under an MIT license. See LICENSE for more information.

Related Awesome Lists
Top Programming Languages
Top Projects

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Swift (65,220
Form (20,216
Provider (15,578
Reusable (2,657
Uitableview (1,336
Uicollectionview (270