May 30, 2020

OTP textfield in iOS swift

By Mohit Agrawal

Design fully customizable OTP textfield in iOS

Overview

Welcome to my new article on how you can design OTP textfield in iOS. Let me show what we are going to design first 😎.

OTP_field
This is what we will design.

Introduction

This tutorial will only cover the design part of the OTP text field, not the validation part. If you want the validation part as well then please let me know in the comment section I will make a separate tutorial for that 👨‍🔧.

Before starting the implementation I just want you to think the possible approach to designing this type of custom field

To design this type of text field I will be using a horizontal type stack view and then I will put four different edit text fields inside the stack view. isn’t it cool? 😎 Let’s start with the coding part.

Implementation

Create a new iOS project in swift. I will just create only one file which will contain all the code. so create a new file and name it OTPView.swift. And write this class inside it.

class OTPTextField: UITextField {
    var previousTextField: UITextField?
    var nextTextFiled: UITextField?
    
    override func deleteBackward() {
        text = ""
        previousTextField?.becomeFirstResponder()
    }
}

Now let me explain what is this class. I have made a custom UITextField and declared two new variables previousTextField and nextTextFiled. These two variables will help us to track which one is going to be the next edit text field while typing the character. Check out the below diagram to understand more. See how well they are connected. Isn’t it like a linked list data structure? Yes, it is basically we are using the linked list concept here.

otp_text_field_stacks
Four different text fields inside a stack.

Now it is time to make stack view class to hold our brand new custom text field. In the same file OTPView.swift write a new class OTPView as shown below.

import UIKit

class OTPView: UIStackView {

    var textFieldArray = [OTPTextField]()
    var numberOfOTPdigit = 4
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupStackView()
        setTextFields()
    }
    
    required init(coder: NSCoder) {
        super.init(coder: coder)
        setupStackView()
        setTextFields()
    }
    
    //To setup stackview
    private func setupStackView() {
        self.backgroundColor = .clear
        self.isUserInteractionEnabled = true
        self.translatesAutoresizingMaskIntoConstraints = false
        self.contentMode = .center
        self.distribution = .fillEqually
        self.spacing = 5
    }
    
    //To setup text fields
    private func setTextFields() {
        for i in 0..<numberOfOTPdigit {
            let field = OTPTextField()
        
            textFieldArray.append(field)
            addArrangedSubview(field)
            field.delegate = self
            field.backgroundColor = .lightGray
            field.layer.opacity = 0.5
            field.textAlignment = .center
            field.layer.shadowColor = UIColor.black.cgColor
            field.layer.shadowOpacity = 0.1
            
            i != 0 ? (field.previousTextField = textFieldArray[i-1]) : ()
            i != 0 ? (textFieldArray[i-1].nextTextFiled = textFieldArray[i]) : ()
        }
    }
}

extension OTPView: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let field = textField as? OTPTextField else {
            return true
        }
        if !string.isEmpty {
            field.text = string
            field.resignFirstResponder()
            field.nextTextFiled?.becomeFirstResponder()
            return true
        }
        return true
    }
}

It is a simple and understandable design. As you can see first I have declared an array to store all the four text fields in one place. Then I have declared a variable to store the total number of the text fields, it can be used to increase the text field if the required OTP number is less or greater then 4.

If you have understood everything till here then you are ready to use our custom text field for OTP. Now go to the Main.storyboard and create a stack view at center and give it width of 200 and height of 50. Then replace the default class with our OTPView class like this.

OTP_class

Now run your code, You will see your brand new custom text field for OTP. Let me know if you face any issues in the comment section. Also if you need source code then go here.

Subscribe YouTube: More tutorials like this

I hope this blog post is useful for you, do let me know your opinion in the comment section below.
I will be happy to see your comments down below 👏.
Thanks for reading!!!