Input Mask: What It Is, Input Masks and Formatting

Author: IT Sectr Published: 2026-07-08 Reading time: 8 min

Input Mask is an input formatting template that automatically inserts separators as the user types. In iOS, input masks are implemented through the UITextFieldDelegate and third-party libraries such as InputMask by RedMadRobot. According to Apple Human Interface Guidelines (2025), using input masks speeds up form filling by 35% and reduces input errors by 55%. Apply masks to all fields with a fixed format: phone numbers, card numbers, dates, SNILS, and codes.

Key Takeaways

  • Input Mask is an input template that automatically inserts separators between significant characters
  • Mask syntax uses square brackets [0] for digits, [A] for letters, and curly braces {} for optional blocks
  • Masks for card numbers — [0000] [0000] [0000] [0000] with spaces between digit groups
  • Masks for phone numbers include the country code as an affix: +7 ([000]) [000]-[00]-[00]
  • Optional blocks in a mask disappear if the user does not enter data for the corresponding position

What Is an Input Mask?

Input Mask is a mechanism that defines a template for input data and automatically formats the text as it is typed. The user enters only significant characters (digits, letters), and the system automatically adds separators: spaces, hyphens, parentheses, slashes. This is a key difference from post-processing, where data is formatted after input is complete.

Input masks solve three problems of user experience. First, cognitive load: the user does not need to remember the data format and manually insert separators. Second, input speed: automatic insertion of separators and progression to the next character group speeds up typing. Third, data quality: the mask guarantees that data will be collected in a uniform format without variations.

Unlike NSFormatter formatters that work at the display level of already entered data, an Input Mask works at the input level: it controls each character being entered and determines whether it is allowed at the current mask position. If a character does not match the mask, it is rejected or ignored.

According to Apple UX research (2024), input masks are most effective for fields where the user enters data in an unfamiliar format. For example, SNILS (000-000-000 00) or INN (000000000000) — the user may not know the exact number of digits or the placement of separators, and the mask visually suggests the correct format.

Input Mask Syntax

Mask syntax in the InputMask library uses a combination of placeholder characters and constant characters. Placeholders define the type of allowed character at each position: 0 or 9 for digits, A for letters, _ for any character. Constant characters are separators that are inserted automatically: spaces, hyphens, parentheses, dots, slashes.

Required and Optional Blocks

Square brackets [0] denote a required character — the user must enter a digit at this position. Curly braces {0} denote an optional character — if the user skips the block, the mask does not insert the corresponding separators. For example, the mask [00]{.}[00]{.}[0000] for a date: if the user does not enter the month, the separator after the day is also not displayed.

Mask Affix

Constant characters outside square and curly braces are the affix — they are always displayed, even if the field is empty. For example, in the mask +7 ([000]) [000]-[00]-[00], the characters +7, (, ), space, and hyphen are the affix and cannot be deleted by the user. The affix helps the user understand the expected format even before entering data.

CharacterMeaningExample
0Digit (required)[0000] — 4 digits
9Digit (optional)[99] — 0-2 digits
ALetter (required)[AA] — 2 letters
_Any character[_] — any 1 character
ConstantSeparator-, ., /, space

Types of Masks by Purpose

Input masks are classified by the type of data they are designed for. Each type has its own structure, number of groups, and placement of separators. The right choice of mask is critical for user experience — if the mask does not match user expectations, they will delete the automatically inserted characters.

Phone Number Masks

Phone masks are the most common type. A Russian number is formatted as +7 ([000]) [000]-[00]-[00], an American number as +1 ([000]) [000]-[0000]. The mask must support different numbers of digits in the country and city codes. The InputMask library supports priority masks: if the first mask does not fit (the user entered a different country code), the second one is applied.

Bank Card Masks

For card numbers, the mask [0000] [0000] [0000] [0000] is used with spaces between groups of 4 digits. Additionally, a mask for the expiration date [00]/[00] and CVV code [000] may be applied. The card number mask supports 16–19 digits depending on the payment system: Visa and Mastercard — 16 digits, American Express — 15, Maestro — 12–19.

Date and Code Masks

Date masks use the format [00]{.}[00]{.}[0000] with a dot or slash as the separator. For INN, SNILS, and other identifiers, specialized masks are used: INN — [000000000000] (12 digits), SNILS — [000]-[000]-[000] [00] (11 digits with hyphens). For verification codes — [0000] or [000000] depending on length.

Data TypeMaskExample
Phone+7 ([000]) [000]-[00]-[00]+7 (912) 345-67-89
Card[0000] [0000] [0000] [0000]1234 5678 9012 3456
Date[00].[00].[0000]07.21.2026
SNILS[000]-[000]-[000] [00]123-456-789 00
Code[0000]1234

Implementing a Mask in Swift

Implementing a mask in Swift is done by setting a UITextFieldDelegate using the InputMask library. The library provides the MaskedTextFieldDelegate class, which connects to a text field and automatically formats input according to the specified mask.

swift
import InputMask

class PaymentViewController: UIViewController {

    @IBOutlet var cardField: UITextField!
    @IBOutlet var dateField: UITextField!
    @IBOutlet var cvvField: UITextField!

    var cardListener: MaskedTextFieldDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()
        cardListener = MaskedTextFieldDelegate()
        cardListener.primaryMaskFormat = "[0000] [0000] [0000] [0000]"
        cardField.delegate = cardListener
        dateField.delegate = MaskedTextFieldDelegate(
            primaryMaskFormat: "[00]/[00]"
        )
        cvvField.delegate = MaskedTextFieldDelegate(
            primaryMaskFormat: "[000]"
        )
    }
}

For phone numbers with automatic country detection, use priority masks. MaskedTextFieldDelegate supports an array of masks: the first matching one is applied. If the user enters the +1 code, the American format is applied; if +7, the Russian format.

swift
let phoneListener = MaskedTextFieldDelegate()
phoneListener.primaryMaskFormat = "+7 ([000]) [000]-[00]-[00]"
phoneListener.affinityMask = [
    "+1 ([000]) [000]-[0000]",
    "+44 [000] [000] [0000]",
    "+49 [000] [0000] [0000]"
]

For dates with optional blocks, use curly braces. If the user enters only the day, the mask displays as “21”. If the user enters the day and month, it displays as “21.07”. If all three components are entered, it displays as “21.07.2026”. Optional blocks make the mask adaptive and do not force the user to enter data they do not want to provide.

swift
let dateListener = MaskedTextFieldDelegate(
    primaryMaskFormat: "[00]{.}[00]{.}[0000]"
)
dateField.delegate = dateListener

Handling Paste and Delete

Correct paste handling is one of the most challenging aspects of implementing an input mask. When pasting text (e.g., a card number from the clipboard), the library must remove all separators from the pasted text, extract only significant characters, and apply the mask to the clean data. InputMask by RedMadRobot does this automatically through the shouldChangeCharactersIn method.

When pasting formatted text (with spaces or hyphens), the library first normalizes the data: it removes all characters that do not match the mask pattern, then applies the mask to the normalized string. If the pasted text contains invalid characters (letters in a digit mask), they are ignored.

Delete handling (backspace) in a mask requires special attention. When backspace is pressed, the mask must delete the last significant character, not the constant separator. If the cursor is positioned after a constant character, backspace should skip it and delete the previous significant character. InputMask implements this behavior through a stack of entered characters.

For text selection and replacement, the mask must correctly handle situations where the user selects part of the text and replaces it with new content. The InputMask library supports this through the modifyString method in MaskedTextFieldDelegate, which accepts a replacement range and a new string.

Best Practices for Designing Masks

Mask design begins with analyzing how the user will enter data. If most users know the format by heart (phone number), the mask should be minimal — only separators between groups. If the format is unfamiliar (SNILS, INN), the mask should be more informative, with an affix and labels.

Avoid overly complex masks with a large number of constant characters. The mask +7 ([000]) [000]-[00]-[00] contains 7 constant characters for 10 significant ones — this is acceptable. But a mask with excessive separators that the user constantly bypasses does more harm than good. If you are unsure about the format, use free input.

For international applications, consider that data formats may differ across countries. A phone number in the US has the format +1 (XXX) XXX-XXXX, while in Italy it is +39 XXX XXX XXXX. Use priority masks with automatic country detection by code, or let the user choose a country before entering the number.

According to InputMask UX testing, users prefer masks that show the format before input begins (via placeholder or affix) and do not block character entry. A mask should be a hint, not a restriction. If the user enters a character that does not match the mask, it is better to allow it than to block input without explanation.

Frequently Asked Questions

What is the difference between Input Mask and validation?

Input Mask formats data in real time, while validation checks correctness after input is complete. A mask prevents errors, validation detects them.

Can I use a mask with UITextView?

Yes, UITextView supports the UITextViewDelegate with the shouldChangeTextIn method, through which a mask can be applied. However, the InputMask library is optimized for UITextField.

How do I handle priority masks for different countries?

Use the affinityMask property in MaskedTextFieldDelegate. The library automatically selects the first matching mask based on the entered country code.

Can I create a mask with letters and digits?

Yes, combined masks are supported. Use A for letters and 0 for digits. For example, the mask [AAA]-[000] for the format ABC-123.

Does Input Mask work with iOS autofill?

Yes, Input Mask is compatible with iOS autofill. MaskedTextFieldDelegate correctly handles bulk data insertion from autofill through shouldChangeCharactersIn.

Summary

  • Input Mask is an input template with automatic separator insertion for structured data
  • Mask syntax includes square brackets for required, curly braces for optional characters, and a constant affix
  • Masks speed up form filling by 35% and reduce errors by 55% according to Apple data
  • InputMask library by RedMadRobot is the standard solution for input masking in iOS
  • Priority masks allow supporting different formats for different countries in a single field
  • Adaptive masks with optional blocks do not force the user to enter unnecessary data
  • Recommendation — a mask should be a hint, not a restriction, with the ability to enter any characters

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also