GithubHelp home page GithubHelp logo

neoneye / swiftyform Goto Github PK

View Code? Open in Web Editor NEW
1.1K 30.0 85.0 1.56 MB

iOS framework for creating forms

License: MIT License

Swift 99.82% Objective-C 0.06% Ruby 0.12%
form uitableview validation uidatepicker uipickerview uislider binding swift ios

swiftyform's Introduction


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

Requirements

  • iOS 12+
  • Xcode 12+
  • Swift 5.1+

Features

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

USAGE

Tutorial 0 - Static text

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

Tutorial 1 - TextField

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

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

Advanced - date picker

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

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:

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:

$ pod install

Carthage

Link to demo project that shows a minimal SwiftyFORM app using Carthage.

To integrate SwiftyFORM into your Xcode project using Carthage, specify it in your Cartfile:

github "neoneye/SwiftyFORM" ~> 1.8

Then, run the following command:

$ 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
  1. Add SwiftyFORM as a submodule by running
$ git submodule add https://github.com/neoneye/SwiftyFORM.git
  1. In the Project Navigator, select your application project and go to "Targets" -> "General"

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

  3. 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]

swiftyform's People

Contributors

asafbaibekov avatar bradleymackey avatar neoneye avatar skyline75489 avatar tawrahim avatar tehprofessor avatar walkersneps avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftyform's Issues

Avatar Row

is it possible to have an AVATAR or USER IMAGE row for settings where you would let the user click on the image to go to an image picker? I can handle the picker but not sure how to get a button of size X:Y as a row?

Custom fonts

Would it be possible to extend this library to allow developers to specify custom fonts in the tableView cell?

Custom validations

Is there a way to include custom validations in SwiftyForms?
An example would be checking if the values in New Password and Repeat Password Field matches.

It would be nice to be able to provide a function to the validate method

iPhone X - landscape

tableview cells are not yet prepared for the iPhone X. The left and right inset is wrong.

simulator screen shot - iphone x - 2017-09-12 at 22 12 46

SwiftyFORM fatal error: init(coder:) has not been implemented

Hello, I am using SwiftyFORM on my ios 9 application..
I've a trouble when implement FormViewController..
The result was: fatal error: init(coder:) has not been implemented
What should i do?

My code was like this:
import UIKit
import SwiftyFORM

class MySwiftyFORMController: FormViewController {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

override func loadView() {
    super.loadView()
    form_installSubmitButton()
}

override func populate(builder: FormBuilder) {
    builder.navigationTitle = "Sign Up"
    builder.toolbarMode = .Simple
    builder.demo_showInfo("SocialNetwork 123\nSign up form")
    builder += SectionHeaderTitleFormItem().title("Details")
    builder += userName
}

lazy var userName: TextFieldFormItem = {
    let instance = TextFieldFormItem()
    instance.title("User Name").placeholder("required")
    instance.keyboardType = .ASCIICapable
    instance.autocorrectionType = .No
    instance.validate(CharacterSetSpecification.lowercaseLetterCharacterSet(), message: "Must be lowercase letters")
    instance.submitValidate(CountSpecification.min(6), message: "Length must be minimum 6 letters")
    instance.validate(CountSpecification.max(8), message: "Length must be maximum 8 letters")
    return instance
    }()

}

Need your advice. Cheers!

DatePicker Shows only a value button?

Hi there,

my datepickers were working fine, but now it shows like in the screenshot, Only todays or setted value like a button in expanded view, and there are no other options - or date picker?

Edit: i ve also tried :

var datePicker: DatePickerFormItem = {
                let instance = DatePickerFormItem()
                instance.title = "Date"
                instance.datePickerMode = .date
                instance.behavior = .expandedAlways
                return instance
            }()
        builder+=datePicker
        build = builder

but this is also shows like mine, no date picker, only one date value looks like a button

Edit: by adding "datePicker.preferredDatePickerStyle = .wheels" like:

func configure(_ model: DatePickerCellModel) {
		datePicker.datePickerMode = model.datePickerMode
		datePicker.minimumDate = model.minimumDate
		datePicker.maximumDate = model.maximumDate
		datePicker.minuteInterval = model.minuteInterval
		datePicker.locale = model.resolvedLocale
		datePicker.date = model.date
        if #available(iOS 13.4, *) {
            datePicker.preferredDatePickerStyle = .wheels
        } else {
            // Fallback on earlier versions
        }
	}

shows the picker old style. But now; you can not interract with wheels, it just shows it.

datepicker

TextViewFormItem and TextFieldFormItem are misaligned

At first, thank you for your work on this great library. It works like a charm!

The only problem I've encountered using version 1.2.0 is, that instances of TextViewFormItem and TextFieldFormItem are shown in full width compared to all other form items, as you can see from the attached screenshot. This problem occurs both on iPad and iPhone.

img_0017

The code used to create the form is listed below:

    override func populate(_ builder: FormBuilder) {
        builder.navigationTitle = "Image Properties"
        builder += SectionHeaderTitleFormItem().title("Image Properties")
        builder += pickStatusFormField
        builder += starsFormField
        builder += colorFormField
        builder += titleFormField
        builder += subtitleFormField

        // ....
    }

    private lazy var titleFormField: TextViewFormItem = {
        let field = TextViewFormItem().title("Title")
        field.value = self.properties.title ?? ""
        return field
    }()

    private lazy var subtitleFormField: TextViewFormItem = {
        let field = TextViewFormItem().title("Subtitle")
        field.value = self.properties.subtitle ?? ""
        return field
    }()

Multiple line for StaticTextFormItem

I have StaticTextFormItem which has long, more than 200 characters, value. Is it possible to expand the form item so that the form item can show all value?

isDirty flag

Is there a concept of if a form is "dirty" (has been edited) vs just displayed that you can check when someone presses a back key to see if anything has been updated?

Changing background color of a button?

Howdy,

I can see references to styleIdentifier and styleClass but can't seem to figure out what they do or how to use them... Any tips? I'm primarily looking for a way to customize the background color of a button (e.g. red for close)? Not sure if I should just inherit and make my own customized class or if you have a sanctioned way of doing it.

Maybe something like...

  lazy var closButton: ButtonFormItem = {
    let instance = ButtonFormItem()
    instance.title("Dismiss")
    instance.backgroundColor = UIColor.redColor()
    instance.action = { [weak self] in
      self?.closeMe()
    }
    return instance
    }()

Thank you!

ViewControllerFormItem and prepareForSegue

Hi!

Is there a way to configure a view controller form item with a custom action so that I can perform a segue and prepare my destination view controller (pass state etc.)?

Thanks

TextView looses focus after first character entry

I've noticed that if you use a TextView, that when you put the cursor in the field and start to type, that after the first character focus is lost. If you click the field again you can then continue typing. It's only on the first character the first time.
I notice that if you go into the example, and try the textview this happens. What is odd is that if you hit clear at the start then the field works correctly. Its only when it has an initial value in it and you start typing that the focus is lost.

Thoughts?

Return key goes to next cell.

Hello,

I was wondering if it was possible to go to the next cell while tapping the return key of the keyboard. I didn't find a method to do this in your example project yet from a TextFieldFormItem for instance.

Thanks a lot!

Manual Installation

CocoaPods and Carthage are awesome tools and make our life really easier, but there are some devs who still don't know how to use them.

It would be cool to add the Manual installation guide in your README.md. You can take a look at my iOS Readme Template to see how you can do it.

Change button color

Hi,

I'm looking for the proper way to change the background color for a ButtonFormItem, but there doesn't seem to be anything built into the framework, and I was wondering if there was a proper way to do this. I tried doing it while overriding reloadForm() but it didn't have my custom color the first time the view loaded.

Thanks,

-Paul

Disable uppercase for Title?

Hi there,

As your document/comment says "SectionHeaderTitleFormItem" only shows Uppercased string, I couldnt disable it. I really would like to show the string as it comes from service.

How do i do that? Any tips?

Bug: Cannot convert value of type

Hello thanks for great plugin!
I got some error I do need your help:

AttributedTextFormItem.swift:19:62: Cannot convert value of type '[String : AnyObject]?' to expected argument type '[NSAttributedStringKey : Any]?'

Thank you

Ability to set autocorrectionType to "no" on initializer

Is there a way to add .autocorrectionType to the initializer? I can't find one unless I create it with a lazy variable?

builder += TextFieldFormItem().title("First Name").placeholder("Enter First Name").keyboardType(.default).autocorrectionType.

Resize Form

Been using SwiftyForm for a month now and love it. Is there a way to resize the form itself so that you could add things above the form - static labels or a segmentedcontrol?

How do I manually validate a form?

I'm trying to validate the form before I make an API call, however I can't seem to find out how the validator works.

Sorry if this isn't the place to be posting this, I'm new to GitHub and iOS development in general. Is there a place I should be posting these questions? Also, is there documentation to your framework anywhere?

Thanks in advance!

Custom FormItem with custom textfield

I've set up a custom textfield class, which I would like to implement into a form item, but I can't seem to find where to do this. I've found the CustomFormItem class, however I'm unsure of where to go from here. How do I add the custom textfield to the CustomFormItem?

This is the custom textfield
`
class PostCodeTextField: UITextField, UITextFieldDelegate {

private var characterLimit: Int?

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    delegate = self
    autocapitalizationType = .allCharacters
}

@IBInspectable var maxLength: Int {
    get {
        guard let length = characterLimit else {
            return Int.max
        }
        return length
    }
    set {
        characterLimit = newValue
    }
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    guard string.characters.count > 0 else {
        return true
    }
    
    let currentText = textField.text ?? ""

    let prospectiveText = (currentText as NSString).replacingCharacters(in: range, with: string)

    return prospectiveText.characters.count <= maxLength
    
}    

`

And I've made a custom class inheriting from CustomFormItem

`
public class PostalCodeFormItem: CustomFormItem {

}
`

Thank in advance!

Error running on phone

Hi i got the following error when i tried running it on my iPhone 6 Plus... Is there any way to solve this problem? I ran the example app directly to test i get the same error as when i did it with my own app.

screen shot 2015-07-12 at 4 55 31 pm

Is there a way get signup example select identifier.

I try to find out how to get selected value , but have not a clue. Could you give me a hint how to do
In SignUpViewController.swift maleOrFemale: ViewControllerFormItem
if let x = context.returnedObject as? SwiftyFORM.OptionRowFormItem
we can get title of user selected, but is there a way to get identifier 1(male)
OptionRow("Male", "1"),
OptionRow("Female", "2"),

Thank you very much

Rounded Corners on Button Row

Is there a way to get access to the button layer to make the corners rounded so that it looks more like a button?

Inline datepicker

Hello!

UI Request.
What about Inline DatePicker like Calendar app in iOS?

OptionPickerFormItem has no 'value' property in DumpVisitor.dump()

In the process of writing this issue, I've found that when dumping my form, my OptionPickerFormItem has no property value, I just solved it by adding dict["value"] = object.selected?.title in visitOptionPicker() . Might want to address it, unless this is the intended behavior? Thanks for this awesome framework!

update SwiftyForm to Swift 4.2

Hi All,

is there any plan to update SwiftyForm to Swift 4.2 ? I tried to use 1.6 and 1.7 with cocoapods seems not working

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.