vikas patidar
vikas patidar

Reputation: 23

what is better approach to UITextField validations on iOS?

I have to make validation on ui text field which used in library called RSFloatInputView.

Here is my xib

import UIKit
import RSFloatInputView

class TextInputLayout: UIView {

    @IBOutlet weak var revealButton: UIButton!
    @IBOutlet weak var warningLabel: UILabel!
    @IBOutlet weak var rsFloatingView: RSFloatInputView!
    var contentView: UIView?

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }

    func xibSetup() {
        contentView = loadViewFromNib()
        contentView!.frame = bounds
        contentView!.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth, UIView.AutoresizingMask.flexibleHeight]
        addSubview(contentView!)
    }

    func loadViewFromNib() -> UIView! {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "TextInputLayout", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
        revealButton.tintColor = Color.grayColor()
        warningLabel.textColor = UIColor.red

        return view
    }  
}

I want to implement this in this view controller, when i click on next button

import UIKit
import DLRadioButton

class SecureWalletViewController: UIViewController,UITextFieldDelegate {

    @IBOutlet weak var securityPinStackView: UIStackView!
    @IBOutlet weak var securityPin: TextInputLayout!
    @IBOutlet weak var confirmSecurityPin: TextInputLayout!

    @IBAction func onNextButtonTap(_ sender: Any) {      

    }

    func textInputLayout(at index:Int) -> TextInputLayout {
        return securityPinStackView.arrangedSubviews[index] as! TextInputLayout
    } 
}

Upvotes: 1

Views: 1362

Answers (4)

Kishan Suthar
Kishan Suthar

Reputation: 658

Use validations for UITextFieldDelegate method like given below:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return true
    }

Or use custom validation function Here

Upvotes: 4

Toseef Khilji
Toseef Khilji

Reputation: 17409

You can use SwiftValidator, It is rule based validator.

let validator = Validator()

   //Register the fields that you want to validate
    validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()])


@IBAction func signupTapped(sender: AnyObject) {
    validator.validate(self)
}

Upvotes: 0

nrx
nrx

Reputation: 369

I'd recommend to use a UITextField subclass with 2 UI states (regular / invalid) and a validation rule (e.g. not empty / match regex / etc)

class ValidationTextField: UITextField {

    enum ValidationRule {
        case notEmpty
//      case matchRegex(regex: NSRegularExpression)
//      ...
    }

    var validationRule: ValidationRule?

    private(set) var isValid:Bool = true {
        didSet {
            updateUIForCurrentState()
        }
    }

    // Call this method on the "next" button click 
    // (or from the delegate on the textFieldDidEndEditing event for early validation)
    func validate() {
        guard let rule = validationRule else {
            // nothing to validate
            return;
        }
        switch rule {
        case .notEmpty:
            if let length = text?.count {
                isValid = length > 0
            }
            else {
                isValid = false
            }
        // process other cases (e.g. matchRegex)
        }
    }

    /// Configure your state-specific layout here.
    private func updateUIForCurrentState() {
        // Current implementation adds a red border in case of invalid input
        if isValid {
            layer.borderWidth = 0
            layer.borderColor = nil
        }
        else {
            layer.borderWidth = 2
            layer.borderColor = UIColor.red.cgColor
        }
    }
}

Upvotes: 0

Sukh
Sukh

Reputation: 1398

 Iam using this 
   // add func in swift class
    struct validatorConstants{
      static let errorMsg = "your error messages"
      static let customMsg = "your error messages"
      static let emailMsg =  "your error messages"
      }
  class Validators: NSObject {

     //MARK: Validation on any Empty TextField
   func validators(TF1:UITextField,errorMsg:String = validatorConstants.errorMsg,fieldName:String = "") -> Bool {
      var error = validatorConstants.errorMsg
            if fieldName.count > 0 {
              error =  fieldName + " is missing"
            }
            if  TF1.text?.isEmpty == true{
               kAppDelegate.showNotification(text: error)
              return false
            }
            return true
          }

          //MARK: Validation on any Email TextField
          func validatorEmail(TF1:UITextField,errorMsg:String = validatorConstants.errorMsg ,errorMsgEmail:String = validatorConstants.emailMsg,fieldName:String = "Email" ) -> Bool {
            var error = validatorConstants.errorMsg
            if fieldName.count > 0 {
                error =  fieldName + " is missing"
            }

            if  TF1.text?.isEmpty == true{
              kAppDelegate.showNotification(text: error)
              return false
            }
            if  TF1.text?.isValidEmail == false{
               kAppDelegate.showNotification(text: errorMsgEmail)
              return false
            }
            return true
          }
        }

   // call this func like this
  // your ViewController 
      var validator:Validators!
  // In viewdidload
      validator = Validators()
  // call this func on button Action
     guard validator.validators(TF1: txtfied,fieldName: "your txtfield name") == false
           else
          {
    //do something what you want
      return
    }
    // Its works for me hope its works for you

Upvotes: 0

Related Questions