Как валидировать email в UITextView
Что проверяют
Умеете ли вы выбрать компонент, место проверки и способ валидации, а не только написать регулярку. Первый уточняющий вопрос почти всегда: почему UITextView, а не UITextField.
Как отвечать
Начните с компонента. Email это одна строка, для него естественнее UITextField. Если по дизайну нужен именно UITextView, настройте его как поле для адреса: он тоже реализует UITextInputTraits, поэтому доступны keyboardType = .emailAddress, textContentType = .emailAddress, autocapitalizationType = .none и autocorrectionType = .no.
Точки проверки в UITextViewDelegate:
textView(_:shouldChangeTextIn:replacementText:): фильтр ввода. Здесь отсекают перенос строки"\n"и пробелы, возвращаяfalse;textViewDidChange(_:): живая проверка, лучше с задержкой через Combine иdebounce, чтобы ошибка не мигала с первой буквы;textViewDidEndEditing(_:): окончательная проверка, когда пользователь ушёл из поля.
Саму проверку вынесите в отдельный тип, например EmailValidator, и покройте юнит-тестами: контроллеру она не нужна. Перед проверкой обрежьте строку через trimmingCharacters(in: .whitespacesAndNewlines). Для формата хватит прагматичной регулярки через NSPredicate(format: "SELF MATCHES %@", pattern) или Regex с wholeMatch(of:) на iOS 16 и новее. Полное соответствие RFC 5322 регуляркой не проверить, и не нужно: настоящая проверка адреса это письмо с подтверждением.
Ошибку показывайте текстом рядом с полем, а не только цветом, иначе её пропустят пользователи с нарушением цветовосприятия и VoiceOver.
Где спотыкаются
Копируют популярную регулярку с [A-Z|a-z]{2,}. Внутри квадратных скобок | это обычный символ, а не «или», и шаблон пропускает вертикальную черту в домене.
Не знают, что textViewDidChange не вызывается при программной установке text. Если поле заполняется из черновика, проверку нужно запустить вручную.
Пишут слишком строгий шаблон и отсекают реальные адреса: с + в локальной части, с длинной доменной зоной или с кириллическим доменом.