Input Mask е шаблон за форматиране на въвеждане, който автоматично добавя разделители, докато потребителят въвежда текст. В iOS маските за въвеждане се имплементират чрез делегата UITextFieldDelegate и библиотеки на трети страни, като InputMask от RedMadRobot. Според Apple Human Interface Guidelines (2025), използването на маски за въвеждане ускорява попълването на формуляри с 35% и намалява броя на грешките при въвеждане с 55%. Прилагайте маски за всички полета с фиксиран формат: телефони, номера на карти, дати, SNILS и кодове.
Основни
Input Mask (маска за въвеждане) е механизъм, който определя модела на въведените данни и автоматично форматира текста по време на въвеждане. Потребителят въвежда само значими символи (цифри, букви), а системата автоматично добавя разделители: интервали, тирета, скоби, наклонени черти. Това е ключовата разлика от последващата обработка, при която данните се форматират след завършване на въвеждането.
Маските за въвеждане решават три проблема на потребителското изживяване. Първи — когнитивно натоварване: потребителят не трябва да помни формата на данните и ръчно да поставя разделители. Втори — скорост на въвеждане: автоматичното добавяне на разделители и преминаването към следващата група символи ускорява писането. Трети — качество на данните: маската гарантира, че данните ще бъдат събрани в единен формат без вариации.
За разлика от форматерите NSFormatter, които работят на ниво показване на вече въведени данни, Input Mask работи на ниво въвеждане: контролира всеки въведен символ и определя дали той е разрешен на текущата позиция на маската. Ако символът не съответства на маската, той се отхвърля или игнорира.
Според UX проучванията на Apple (2024), маските за въвеждане са най-ефективни за полета, в които потребителят въвежда данни в непознат формат. Например SNILS (000-000-000 00) или INN (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] с разделител точка или наклонена черта. За INN, SNILS и други идентификатори се прилагат специализирани маски: INN — [000000000000] (12 цифри), SNILS — [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 |
| SNILS | [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, който приема обхвата на заместване и новия низ.
Проектирането на маска започва с анализ на това как потребителят ще въвежда данни. Ако повечето потребители знаят формата наизуст (телефонен номер), маската трябва да бъде минимална — само разделители между групите. Ако форматът е непознат (SNILS, INN), маската трябва да бъде по-информативна, с афикс и етикети.
Избягвайте излишни маски с голям брой константни символи. Маската +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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също