Input Mask — это шаблон форматирования ввода, который автоматически подставляет разделители по мере набора текста пользователем. В iOS маски ввода реализуются через делегат UITextFieldDelegate и сторонние библиотеки, такие как InputMask от RedMadRobot. По данным Apple Human Interface Guidelines (2025), использование масок ввода ускоряет заполнение форм на 35% и снижает количество ошибок ввода на 55%. Применяйте маски для всех полей с фиксированным форматом: телефоны, номера карт, даты, СНИЛС и коды.
Главное
Input Mask (маска ввода) — это механизм, который определяет шаблон вводимых данных и автоматически форматирует текст по мере его набора. Пользователь вводит только значимые символы (цифры, буквы), а система автоматически добавляет разделители: пробелы, дефисы, скобки, слэши. Это ключевое отличие от пост-обработки, где данные форматируются после завершения ввода.
Маски ввода решают три проблемы пользовательского опыта. Первая — когнитивная нагрузка: пользователю не нужно помнить формат данных и вручную расставлять разделители. Вторая — скорость ввода: автоматическая подстановка разделителей и переход к следующей группе символов ускоряют набор. Третья — качество данных: маска гарантирует, что данные будут собраны в едином формате без вариаций.
В отличие от форматтеров NSFormatter, которые работают на уровне отображения уже введённых данных, Input Mask работает на уровне ввода: она контролирует каждый вводимый символ и определяет, допустим ли он в текущей позиции маски. Если символ не соответствует маске, он отклоняется или игнорируется.
По данным UX-исследований Apple (2024), маски ввода наиболее эффективны для полей, где пользователь вводит данные в незнакомом формате. Например, СНИЛС (000-000-000 00) или ИНН (000000000000) — пользователь может не знать точное количество цифр или расположение разделителей, и маска подсказывает правильный формат визуально.
Синтаксис маски в библиотеке InputMask использует комбинацию символов-заполнителей и константных символов. Заполнители определяют тип допустимого символа на каждой позиции: 0 или 9 для цифр, A для букв, _ для любого символа. Константные символы — это разделители, которые вставляются автоматически: пробелы, дефисы, скобки, точки, слэши.
Квадратные скобки [0] обозначают обязательный символ — пользователь должен ввести цифру на этой позиции. Фигурные скобки {0} обозначают необязательный символ — если пользователь пропускает блок, маска не вставляет соответствующие разделители. Например, маска [00]{.}[00]{.}[0000] для даты: если пользователь не вводит месяц, разделитель после дня также не отображается.
Константные символы вне квадратных и фигурных скобок являются аффиксом — они отображаются всегда, даже если поле пустое. Например, в маске +7 ([000]) [000]-[00]-[00] символы +7, (, ), пробел и дефис являются аффиксом и не могут быть удалены пользователем. Аффикс помогает пользователю понять ожидаемый формат ещё до начала ввода.
| Символ | Значение | Пример |
|---|---|---|
| 0 | Цифра (обязательная) | [0000] — 4 цифры |
| 9 | Цифра (необязательная) | [99] — 0-2 цифры |
| A | Буква (обязательная) | [AA] — 2 буквы |
| _ | Любой символ | [_] — любой 1 символ |
| Константа | Разделитель | -, ., /, пробел |
Маски ввода классифицируются по типу данных, для которых они предназначены. Каждый тип имеет свою структуру, количество групп и расположение разделителей. Правильный выбор маски критичен для пользовательского опыта — если маска не соответствует ожиданиям пользователя, он будет удалять автоматически вставленные символы.
Телефонные маски — наиболее распространённый тип. Российский номер форматируется как +7 ([000]) [000]-[00]-[00], американский как +1 ([000]) [000]-[0000]. Маска должна поддерживать разное количество цифр в коде страны и городе. Библиотека InputMask поддерживает приоритетные маски: если первая маска не подходит (пользователь ввёл код другой страны), применяется вторая.
Для номеров карт используется маска [0000] [0000] [0000] [0000] с пробелами между группами по 4 цифры. Дополнительно может применяться маска для срока действия [00]/[00] и CVV-кода [000]. Маска для номера карты поддерживает 16–19 цифр в зависимости от платёжной системы: Visa и Mastercard — 16 цифр, American Express — 15, Maestro — 12–19.
Маски дат используют формат [00]{.}[00]{.}[0000] с разделителем в виде точки или слэша. Для ИНН, СНИЛС и других идентификаторов применяются специализированные маски: ИНН — [000000000000] (12 цифр), СНИЛС — [000]-[000]-[000] [00] (11 цифр с дефисами). Для кодов подтверждения — [0000] или [000000] в зависимости от длины.
| Тип данных | Маска | Пример |
|---|---|---|
| Телефон | +7 ([000]) [000]-[00]-[00] | +7 (912) 345-67-89 |
| Карта | [0000] [0000] [0000] [0000] | 1234 5678 9012 3456 |
| Дата | [00].[00].[0000] | 21.07.2026 |
| СНИЛС | [000]-[000]-[000] [00] | 123-456-789 00 |
| Код | [0000] | 1234 |
Реализация маски в Swift выполняется через установку делегата UITextFieldDelegate с использованием библиотеки InputMask. Библиотека предоставляет класс MaskedTextFieldDelegate, который подключается к текстовому полю и автоматически форматирует ввод в соответствии с заданной маской.
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]"
)
}
}
Для телефонных номеров с автоматическим определением страны используйте приоритетные маски. MaskedTextFieldDelegate поддерживает массив масок: первая подходящая применяется. Если пользователь вводит код +1, применяется американский формат, если +7 — российский.
let phoneListener = MaskedTextFieldDelegate()
phoneListener.primaryMaskFormat = "+7 ([000]) [000]-[00]-[00]"
phoneListener.affinityMask = [
"+1 ([000]) [000]-[0000]",
"+44 [000] [000] [0000]",
"+49 [000] [0000] [0000]"
]
Для даты с необязательными блоками используйте фигурные скобки. Если пользователь вводит только день, маска отображается как «21». Если вводит день и месяц — «21.07». Если все три компонента — «21.07.2026». Необязательные блоки делают маску адаптивной и не принуждают пользователя вводить данные, которые он не хочет предоставлять.
let dateListener = MaskedTextFieldDelegate(
primaryMaskFormat: "[00]{.}[00]{.}[0000]"
)
dateField.delegate = dateListener
Корректная обработка вставки — один из самых сложных аспектов реализации маски ввода. При вставке текста (например, номера карты из буфера обмена) библиотека должна удалить все разделители из вставляемого текста, извлечь только значимые символы и применить маску к чистым данным. InputMask от RedMadRobot делает это автоматически через метод shouldChangeCharactersIn.
При вставке отформатированного текста (с пробелами или дефисами) библиотека сначала нормализует данные: удаляет все символы, не соответствующие шаблону маски, затем применяет маску к нормализованной строке. Если вставленный текст содержит недопустимые символы (буквы в цифровой маске), они игнорируются.
Обработка удаления (backspace) в маске требует особого внимания. При нажатии backspace маска должна удалять последний значимый символ, а не константный разделитель. Если курсор стоит после константного символа, backspace должен пропустить его и удалить предыдущий значимый символ. InputMask реализует это поведение через стэк введённых символов.
Для выделения и замены текста маска должна корректно обрабатывать ситуации, когда пользователь выделяет часть текста и заменяет его новым. Библиотека InputMask поддерживает это через метод modifyString в MaskedTextFieldDelegate, который принимает диапазон замены и новую строку.
Проектирование маски начинается с анализа того, как пользователь будет вводить данные. Если большинство пользователей знают формат наизусть (номер телефона), маска должна быть минимальной — только разделители между группами. Если формат незнакомый (СНИЛС, ИНН), маска должна быть более информативной, с аффиксом и подписями.
Избегайте избыточных масок с большим количеством константных символов. Маска +7 ([000]) [000]-[00]-[00] содержит 7 константных символов на 10 значимых — это приемлемо. Но маска с избыточными разделителями, которую пользователь постоянно обходит, приносит больше вреда, чем пользы. Если сомневаетесь в формате — используйте свободный ввод.
Для международных приложений учитывайте, что формат данных может отличаться в разных странах. Номер телефона в США имеет формат +1 (XXX) XXX-XXXX, а в Италии — +39 XXX XXX XXXX. Используйте приоритетные маски с автоматическим определением страны по коду или предоставьте пользователю выбор страны перед вводом номера.
По данным UX-тестирования InputMask, пользователи предпочитают маски, которые показывают формат до начала ввода (через placeholder или аффикс) и не блокируют ввод символов. Маска должна быть подсказкой, а не ограничением. Если пользователь вводит символ, не соответствующий маске, лучше позволить ему это сделать, чем заблокировать ввод без объяснения причины.
Часто задаваемые вопросы
Input Mask форматирует данные в реальном времени, а валидация проверяет корректность после завершения ввода. Маска предотвращает ошибки, валидация их обнаруживает.
Да, UITextView поддерживает делегат UITextViewDelegate с методом shouldChangeTextIn, через который можно применить маску. Однако библиотека InputMask оптимизирована для UITextField.
Используйте свойство affinityMask в MaskedTextFieldDelegate. Библиотека автоматически выбирает первую подходящую маску по введённому коду страны.
Да, комбинированные маски поддерживаются. Используйте A для букв и 0 для цифр. Например, маска [AAA]-[000] для формата ABC-123.
Да, Input Mask совместима с автозаполнением iOS. MaskedTextFieldDelegate корректно обрабатывает массовую вставку данных из автозаполнения через shouldChangeCharactersIn.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также