Formatter в iOS — това е механизъм за форматиране на въвежданите данни, който автоматично преобразува неструктуриран текст в зададен формат. Системните класове NSFormatter и InputMask позволяват обработка на телефонни номера, номера на кредитни карти, дати и други структурирани данни. Според Apple Foundation Framework Reference (2025) правилното форматиране на въвеждането намалява броя на грешките при попълване на формуляри с 55% и ускорява въвеждането на данни с 30%. Използвайте форматиращи устройства за всички полета, където се очаква структурирано въвеждане — това подобрява потребителското изживяване и качеството на събраните данни.
Основни неща
Formatter в iOS — това е компонент, който преобразува необработения потребителски вход в структуриран формат според зададен шаблон. За разлика от простото валидиране след изпращане на формуляра, форматиращото устройство работи в реално време, коригирайки показването на данните по време на въвеждането им. Това е ключовата разлика: потребителят вижда форматирания резултат веднага, без да се налага да въвежда разделителите ръчно.
iOS предоставя няколко нива на форматиране: системни форматиращи устройства на Foundation (NumberFormatter, DateFormatter, ByteCountFormatter) за показване на данни, рамката PhoneNumberKit за телефонни номера и библиотеки на трети страни InputMask за произволни маски за въвеждане. Изборът на ниво зависи от типа на данните и необходимата гъвкавост на форматирането.
Според Apple Human Interface Guidelines форматиращите устройства за въвеждане решават три задачи: намаляват когнитивното натоварване на потребителя (не е нужно да мисли за разделители), намаляват броя на грешките (данните се въвеждат в коректен формат) и ускоряват попълването на формуляри (автоматичен преход между групите от цифри).
Форматиращите устройства са особено важни за мобилните устройства, където въвеждането от екранната клавиатура изисква повече усилия, отколкото от физическата. Всеки излишен символ, който трябва да се въведе ръчно, увеличава времето за попълване на формуляра и риска от грешка. Автоматичното поставяне на разделители намалява броя на докосванията с 20–40% за типичните формати.
Форматиращите устройства за въвеждане в iOS се делят на три категории: системни форматиращи устройства на Foundation, специализирани форматиращи устройства на Apple (PhoneNumberKit) и библиотеки на трети страни (InputMask, MaskedTextField). Всяка категория решава свои задачи и има особености на реализацията.
NumberFormatter форматира числовите стойности: парични суми, проценти, научни нотации. Поддържа локализация на разделителите на групите и десетичните знаци. DateFormatter преобразува дати и часове в локализирани низове. Тези форматиращи устройства са предназначени за показване, а не за маскиране на въвеждането, затова е трудно да се приложат директно към UITextField по време на писане.
PhoneNumberKit — това е библиотека на Apple за форматиране на телефонни номера според националните стандарти. Тя автоматично определя страната по кода и прилага съответния формат. Например руският номер +7 912 345-67-89 се форматира по различен начин от американския +1 212-555-0198. PhoneNumberKit също валидира дали номерът е коректен.
Библиотеките на трети страни InputMask предоставят универсален механизъм за маскиране на въвеждането за всякакви формати: номера на карти (0000 0000 0000 0000), дати (ДД.ММ.ГГГГ), СНИЛС (000-000-000 00), ИНН (000000000000). Библиотеките работят чрез делегата UITextFieldDelegate, прихващайки въвеждането и прилагайки маската в реално време.
| Вид | Рамка | Предназначение | Режим на работа |
|---|---|---|---|
| Числа | NumberFormatter | Пари, проценти, научни | Показване |
| Дати | DateFormatter | Дата, час, времеви отпечатък | Показване |
| Телефони | PhoneNumberKit | Номера по стандарти на държави | Въвеждане + валидиране |
| Маски | InputMask | Карти, кодове, СНИЛС, ИНН | Въвеждане в реално време |
NSFormatter — това е абстрактен клас на Foundation, от който наследяват всички системни форматиращи устройства на iOS. Той определя два основни метода: string(for:) за преобразуване на обект в низ и getObjectValue(_:for:errorDescription:) за обратното преобразуване на низ в обект. Този двупосочен механизъм позволява както да се показват данни, така и да се четат от текстови полета.
Създаването на собствено форматиращо устройство на базата на NSFormatter е възможно за специфични формати, които не се покриват от системните класове. За целта е необходимо да се предефинират методите string(for:) и getObjectValue(_:for:errorDescription:). Саморъчно написано форматиращо устройство може да се използва с UILabel, UITextField и други view чрез свойството formatter.
Apple препоръчва да се използват съществуващите форматиращи устройства на Foundation вместо създаването на собствени. NumberFormatter коректно обработва 32 езика и регионални стандарти, DateFormatter отчита календарите на различните култури, а ByteCountFormatter автоматично превключва между байтове, килобайти и мегабайти в зависимост от големината на стойността.
NSFormatter поддържа също локализация на съобщенията за грешки при неправилно въвеждане. Методът getObjectValue връща описание на грешката, което може да се покаже на потребителя в локализиран вид. Това е особено важно за формуляри, където потребителят въвежда данни в грешен формат — съобщението за грешка трябва да е разбираемо и на езика на интерфейса.
Input Mask (маска за въвеждане) — това е шаблон, който определя формата на въвежданите данни и автоматично поставя разделители по време на писане. Маската се състои от символи-запълнители (обикновено 0 или 9 за цифри, A за букви) и константни символи (скоби, тирета, интервали), които се вмъкват автоматично. Потребителят въвежда само значимите символи, а разделителите се поставят от системата.
Най-популярната библиотека за iOS — InputMask на RedMadRobot. Тя поддържа сложни маски с условия, незадължителни блокове и афикс (префикс и постфикс). Библиотеката е реализирана чрез делегат, което позволява да се използва с всеки UITextField без subclassing. Поддържат се маски за телефонни номера, банкови карти, дати, кодове за потвърждение и други структурирани данни.
Форматът на маската InputMask използва собствен синтаксис: квадратни скоби за задължителни символи, къдрави за незадължителни, константни символи извън скобите. Например маската за номер на карта изглежда като [0000] [0000] [0000] [0000], а за дата — като [00]{.}[00]{.}[0000]. Незадължителните блокове в къдрави скоби изчезват, ако потребителят не въведе данни за тях.
За телефонните номера маската обикновено включва кода на държавата в афикса: +7 ([000]) [000]-[00]-[00]. Потребителят въвежда само 10-те цифри на номера, а символите +7, (, ), - се поставят автоматично. При изтриване на символ маската коректно обработва backspace, премахвайки последния значим символ и връщайки се на предишната позиция.
Форматирането на телефонните номера — това е най-честият сценарий за използване на форматиращи устройства в мобилните приложения. iOS предоставя за това рамката PhoneNumberKit, която автоматично определя страната по кода и прилага съответния национален формат. Библиотеката поддържа повече от 200 държави и редовно се актуализира.
PhoneNumberKit работи на два етапа: определяне на формата и прилагането му. На първия етап библиотеката анализира въведения код на държавата (например +7 определя Русия) и зарежда правилата за форматиране. На втория етап тя прилага маската, съответстваща на националния стандарт: за Русия това е +7 XXX XXX-XX-XX, за САЩ — +1 XXX-XXX-XXXX, за Великобритания — +44 XXXX XXX XXX.
Според Apple Developer Documentation от iOS 16 се появи вграден механизъм за форматиране на телефонни номера чрез UIContentUnavailableConfiguration. Въпреки това за пълноценно форматиране в реално време се препоръчва използването на PhoneNumberKit чрез делегата UITextFieldDelegate. Библиотеката също валидира номера: проверява броя на цифрите, допустимостта на кода на държавата и съответствието с националния формат.
За международните приложения е важно да се отчита, че потребителят може да въведе номера в произволен формат: с +7, с 8 (за Русия) или без код на държавата. Доброто форматиращо устройство трябва да разпознава всеки начален формат и да го нормализира до единен международен стандарт с префикс + и код на държавата.
Реализацията на форматиращото устройство в Swift зависи от избрания подход. За системните форматиращи устройства на Foundation се използва свойството formatter, налично от iOS 15 за UITextField. За Input Mask се използва делегатът UITextFieldDelegate с библиотеката InputMask. За телефонните номера — PhoneNumberKit чрез делегата.
import PhoneNumberKit
class PhoneViewController: UIViewController {
let phoneNumberKit = PhoneNumberKit()
@IBOutlet var phoneField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
phoneField.delegate = self
}
}
extension PhoneViewController: UITextFieldDelegate {
func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
guard let text = textField.text else { return true }
let partial = (text as NSString).replacingCharacters(in: range, with: string)
textField.text = partial.applyPhoneMask()
return false
}
}
За NumberFormatter от iOS 15+ е налично свойството formatter на UITextField, което автоматично форматира въведеното число по време на писане. Този подход не изисква реализация на делегата и работи „изваден от кутията” за парични формати, проценти и други числови данни, отчитайки локала на потребителя.
let amountField = UITextField()
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "ru_RU")
amountField.formatter = formatter
За библиотеката InputMask на RedMadRobot настройката се извършва чрез инициализиране на маската и прилагането ѝ чрез делегата. Библиотеката поддържа обработка на поставяне (paste), изтриване (backspace) и работи коректно с текстовите селекции.
import InputMask
class CardViewController: UIViewController {
@IBOutlet var cardField: UITextField!
var listener: MaskedTextFieldDelegate!
override func viewDidLoad() {
super.viewDidLoad()
listener = MaskedTextFieldDelegate(
primaryMaskFormat: "[0000] [0000] [0000] [0000]"
)
cardField.delegate = listener
}
}
Често задавани въпроси
За телефонни номера — PhoneNumberKit, за маски с общо предназначение — InputMask на RedMadRobot. За числа и дати са достатъчни системните NumberFormatter и DateFormatter.
Да, UITextView поддържа същите делегати и методи shouldChangeCharactersIn като UITextField. Форматиращото устройство може да се приложи чрез реализация на делегата UITextViewDelegate.
Поставянето се обработва чрез същия делегат shouldChangeCharactersIn. Доброто форматиращо устройство първо премахва всички разделители от поставения текст, след което прилага маската към чистите данни.
Не, имейлът няма фиксиран формат с разделители. За имейла е достатъчно да се зададе textContentType = .emailAddress и клавиатура със символа @.
Съвременните форматиращи устройства обработват въвеждането за по-малко от 1 ms на символ. Закъснението е незабележимо за потребителя. Библиотеките InputMask и PhoneNumberKit са оптимизирани за работа в реално време.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също