UITextView — це багаторядковий текстовий компонент UIKit, що успадковує UIScrollView та підтримує редагування атрибутованого тексту з вбудовуванням посилань і зображень. За документацією Apple Developer (2025), UITextView надає UITextViewDelegate з колбеками textViewDidChange, shouldInteractWithURL та shouldInteractWithTextAttachment для обробки взаємодій. На відміну від UITextField, UITextView підтримує прокручування, текстові стилі через typingAttributes та dataDetectorTypes для автоматичного визначення посилань, адрес і дат. Це основний компонент для відображення вмісту та введення багаторядкового тексту в застосунках iOS.
Головне
UITextView — це компонент UIKit, призначений для відображення та редагування багаторядкового тексту. На відміну від UILabel, UITextView підтримує виділення тексту, редагування, прокручування при перевищенні розмірів та атрибутований текст. Будучи спадкоємцем UIScrollView, UITextView автоматично включає вертикальне та горизонтальне прокручування при перевищенні вмісту — це налаштовується через isScrollEnabled. Клас підтримує редагування через властивість isEditable: встановіть false для режиму лише читання. UITextView працює з NSLayoutManager через систему TextKit: NSTextStorage (зберігання атрибутованого тексту) → NSLayoutManager (розмітка рядків) → NSTextContainer (геометрія області тексту). Ця архітектура дозволяє створювати кастомне верстання з обтіканням зображень, багатоколонковий текст і складні текстові макети. UITextView використовується для відображення статей, описів, логів, коментарів та будь-яких багаторядкових текстів у iOS.
Різниця між UITextView та UITextField виходить далеко за межі кількості рядків. UITextField — однорядковий UIControl з підтримкою placeholder, left/right view та clear button. UITextView — багаторядковий UIScrollView з повноцінною системою TextKit для атрибутованого тексту. UITextField не підтримує NSAttributedString на рівні відображення (тільки через attributedText з обмеженнями), UITextView обробляє NSAttributedString повністю з різними шрифтами, параграф-стайлами та вбудованими зображеннями. UITextField має вбудовану кнопку очищення (clearButtonMode), UITextView її не має — потрібна кастомна реалізація. UITextView автоматично змінює свій розмір під вміст (intrinsicContentSize), UITextView потребує ручного керування висотою через contentSize спостереження або Auto Layout constraint. UITextView підтримує dataDetectorTypes (автоматичне визначення посилань), UITextField підтримує його з iOS 16+. Для введення багаторядкового тексту (коментарі, нотатки, повідомлення) вибирайте UITextView. Для полів форми (ім'я, email, пароль) використовуйте UITextField.
| Можливість | UITextView | UITextField |
|---|---|---|
| Рядки | Багаторядковий | Однорядковий |
| Placeholder | Немає (кастомний) | Вбудований |
| Атрибути тексту | Повний NSAttributedString | Обмежений |
| Data Detectors | Повна підтримка | iOS 16+ |
| Зображення inline | Через NSTextAttachment | Не підтримується |
| Прокручування | Вбудоване (UIScrollView) | Немає |
| Left/Right View | Немає | Вбудовані |
NSAttributedString — це фундаментальна можливість UITextView, що відрізняє його від UITextField та UILabel. Атрибутований рядок дозволяє задавати різні шрифти, кольори, міжрядкові інтервали, вирівнювання та посилання в рамках одного тексту. Властивості: textView.attributedText = attributedString. Ключові атрибути NSAttributedString.Key: font (.systemFont, .boldSystemFont, кастомний UIFont), foregroundColor, backgroundColor, paragraphStyle (NSMutableParagraphStyle з lineSpacing, alignment, lineBreakMode), link (URL для інтерактивних посилань), underlineStyle, strikethroughStyle, shadow, baselineOffset, kern (міжлітерний інтервал). Для створення attributedString використовуйте init(string:, attributes:) або NSMutableAttributedString для додавання атрибутів до різних діапазонів. UITextView автоматично відображає посилання (link attribute) як інтерактивні — при натисканні викликається делегатний метод shouldInteractWithURL. Для скидання атрибутів для нового введення використовуйте typingAttributes.
import UIKit
let textView = UITextView()
textView.isEditable = false
textView.isScrollEnabled = true
textView.dataDetectorTypes = [.link, .phoneNumber]
let attributedString = NSMutableAttributedString(
string: "Visit our website or call +1-800-555-0199"
)
attributedString.addAttributes([
.font: UIFont.systemFont(ofSize: 16),
.foregroundColor: UIColor.label,
], range: NSRange(location: 0, length: 11))
let linkRange = (attributedString.string as NSString)
.range(of: "website")
attributedString.addAttributes([
.link: URL(string: "https://example.com")!,
.foregroundColor: UIColor.systemBlue,
], range: linkRange)
textView.attributedText = attributedString
UITextViewDelegate — це протокол, що керує редагуванням та взаємодією з текстом. Основні методи: textViewDidBeginEditing(textView) — викликається при старті редагування; textViewDidEndEditing — при завершенні; textViewDidChange — при кожній зміні тексту; textViewDidChangeSelection — при зміні виділення; textViewShouldInteractWithURL — при натисканні на посилання (повертає Bool, чи дозволено перехід); textViewShouldInteractWithTextAttachment — при натисканні на вбудоване зображення. Для обробки посилань всередині UITextView перевизначте shouldInteractWithURL — у ньому можна: відкрити URL у SFSafariViewController, показати UIAlertController для підтвердження, обробити кастомні URL schemes. Важливо: якщо textView.isEditable = true, посилання стають недоступними для натискання до подвійного тапу — для інтерактивних посилань при редагуванні використовуйте gesture recognizers.
SFSafariViewController — стандартний спосіб відкриття посилань у застосунках iOS. У методі shouldInteractWithURL створіть SFSafariViewController з URL та представте його модально або через navigationController. Для універсальних посилань використовуйте UIApplication.shared.open(url, options) — але це виходить за межі застосунку. Для заборони відкриття посилань поверніть false у shouldInteractWithURL та обробіть URL самостійно.
NSTextContainer — частина архітектури TextKit, що визначає геометричну область, у якій відображається текст UITextView. Кожен UITextView має стандартний textContainer, налаштовуваний через: textView.textContainerInset — відступи тексту від меж textView (UIEdgeInsets); textView.textContainer.lineFragmentPadding — горизонтальний відступ всередині кожного рядка; textView.textContainer.maximumNumberOfLines — обмеження кількості рядків (0 = без ліміту); textView.textContainer.exclusionPaths — масив UIBezierPath для областей, які текст має обтікати (зображення, кастомні shapes). ExclusionPaths дозволяють створювати складне верстання: текст обтікає кругле зображення профілю, іконку або будь-який довільний контур. Для динамічного розміру UITextView спостерігайте contentSize через KVO або делегат та оновлюйте constraints.
// Dynamic UITextView height via contentSize
func textViewDidChange(textView: UITextView) {
let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(
CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude)
)
heightConstraint.constant = newSize.height
UIView.animate(withDuration: 0.1) {
self.view.layoutIfNeeded()
}
}
// ExclusionPath for image wrapping
let imageFrame = CGRect(x: 16, y: 100, width: 80, height: 80)
let exclusionPath = UIBezierPath(rect: imageFrame)
textView.textContainer.exclusionPaths = [exclusionPath]
dataDetectorTypes — властивість UITextView, яка автоматично розпізнає та робить інтерактивними певні типи даних у тексті: .link (URL, email), .phoneNumber (телефонні номери), .address (адреси), .calendarEvent (дати та події), .flightNumber (номери рейсів), .lookupSuggestion (пошукові підказки), .trackingNumber (трекінг-номери), .money (суми), .shipmentTrackingNumber, .all (всі типи). Data Detector працює з NSDataDetector та URL, автоматично підсвічуючи виявлені дані. Для кастомізації обробки встановіть dataDetectorTypes та перевизначте shouldInteractWithURL у делегаті. Важливо: dataDetectorTypes працює тільки для URL та phoneNumber без додаткового налаштування — інші типи можуть вимагати iOS 16+. Data Detector не конфліктує з link attribute у NSAttributedString — обидва механізми працюють паралельно. Для UITextView лише читання з вмістом (новини, статті) встановіть dataDetectorTypes = [.link, .phoneNumber].
Розглянемо два практичні приклади використання UITextView у застосунках iOS. Перший — read-only text view з атрибутованим текстом та data detector для відображення вмісту. Другий — редагований text view з лінивим placeholder та динамічною висотою для форми коментаря. Обидва приклади використовують best practices UIKit: делегатний протокол, Auto Layout та TextKit.
Read-only режим вмикається встановленням isEditable = false та isSelectable = true. Це дозволяє користувачеві виділяти текст та натискати на посилання, але не редагувати. Встановіть dataDetectorTypes для автоматичного визначення посилань, backgroundColor = .clear для прозорого фону. Для відображення довгого вмісту використовуйте attributedText з NSMutableParagraphStyle lineSpacing для читабельності. Додайте link attributes для ключових посилань всередині тексту.
import UIKit
class ArticleViewController: UIViewController {
let contentView = UITextView()
override func viewDidLoad() {
super.viewDidLoad()
contentView.isEditable = false
contentView.isSelectable = true
contentView.dataDetectorTypes = [.link, .phoneNumber]
contentView.backgroundColor = .clear
contentView.textContainerInset = UIEdgeInsets(
top: 8, left: 16,
bottom: 8, right: 16
)
contentView.delegate = self
loadArticleContent()
}
func loadArticleContent() {
guard let url = URL(string: "https://example.com/article")
else { return }
// Load content from URL and set attributedText
}
}
Placeholder для UITextView не вбудований — реалізуйте його через UILabel поверх textView або через attributedText з перевіркою isEmpty. Простий підхід: UILabel з сірим текстом, який ховається при початку редагування. У textViewDidChange перевіряйте наявність тексту та ховайте/показуйте placeholder. Для більш елегантного рішення використовуйте властивість typingAttributes для встановлення кольору тексту, що вводиться. Динамічна висота textView досягається через спостереження contentSize та оновлення constraints — це стандартний патерн для чатів та форм коментарів.
Часті запитання
UITextView не має вбудованого placeholder. Стандартне рішення: додайте UILabel з сірим текстом поверх textView. У textViewDidBeginEditing ховайте label, у textViewDidEndEditing показуйте, якщо текст порожній. Альтернативно: використовуйте attributedText з сірим кольором як placeholder та скидайте при початку редагування. Для готового рішення використовуйте бібліотеку KMPlaceholderTextView або ReactorKit.
Встановіть textContainerInset = .zero та lineFragmentPadding = 0: textView.textContainerInset = UIEdgeInsets.zero; textView.textContainer.lineFragmentPadding = 0. Додатково: textView.contentInset = .zero. Це повністю видалить відступи від країв textView до тексту. Врахуйте, що lineFragmentPadding за замовчуванням дорівнює 5.
Перевірте: isSelectable = true (необхідно для взаємодії), dataDetectorTypes включає .link, делегат не повертає false у shouldInteractWithURL. Якщо textView.isEditable = true, посилання недоступні для одноразового натискання — потрібен подвійний тап. Для інтерактивних посилань у редагованому textView додайте UITapGestureRecognizer поверх textView та обробляйте URL вручну.
Встановіть isScrollEnabled = true та додайте height constraint з фіксованим значенням. Текст, що перевищує висоту, буде прокручуватися. Для оптимального UX використовуйте maxHeight: спостерігайте contentSize та встановлюйте height constraint не вище maxHeight. При перевищенні maxHeight вмикайте scrollEnabled. Це стандартний патерн для полів введення повідомлень та коментарів.
Використовуйте NSTextAttachment: створіть об'єкт, встановіть image та bounds, потім створіть NSAttributedString з attachment та вставте в textView.attributedText. Приклад: let attachment = NSTextAttachment(); attachment.image = image; attachment.bounds = CGRect(x, y, width, height); let attributedString = NSAttributedString(attachment: attachment). Зображення відобразиться inline в тексті та буде прокручуватися разом із ним.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також