UITextView е многоредов текстов компонент на UIKit, наследяващ UIScrollView и поддържащ редактиране на атрибутиран текст с вграждане на връзки и изображения. Според документацията на Apple Developer (2025), UITextView предоставя UITextViewDelegate с callback-ове 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 и бутон за изчистване. UITextView е многоредов UIScrollView с пълноценна система TextKit за атрибутиран текст. UITextField не поддържа NSAttributedString на ниво показване (само чрез attributedText с ограничения), UITextView обработва напълно NSAttributedString с различни шрифтове, стилове на абзаци и вградени изображения. UITextField има вграден бутон за изчистване (clearButtonMode), UITextView няма — изисква персонализирана имплементация. UITextField автоматично променя размера си според съдържанието (intrinsicContentSize), UITextView изисква ръчно управление на височината чрез наблюдение на contentSize или ограничения на Auto Layout. UITextView поддържа dataDetectorTypes (автоматично откриване на връзки), UITextField ги поддържа от iOS 16+. За въвеждане на многоредов текст (коментари, бележки, съобщения) изберете UITextView. За полета на формуляри (име, имейл, парола) използвайте 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 схеми. Важно: ако 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 за области, които текстът трябва да заобикаля (изображения, персонализирани форми). ExclusionPaths позволяват създаване на сложно оформление: текстът обтича кръгла профилна снимка, икона или произволен контур. За динамичен размер на UITextView наблюдавайте contentSize чрез KVO или делегат и актуализирайте ограниченията.
// Динамична височина на UITextView чрез 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 за обтичане на изображения
let imageFrame = CGRect(x: 16, y: 100, width: 80, height: 80)
let exclusionPath = UIBezierPath(rect: imageFrame)
textView.textContainer.exclusionPaths = [exclusionPath]
dataDetectorTypes — свойство на UITextView, което автоматично разпознава и прави интерактивни определени типове данни в текста: .link (URL, имейл), .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 приложения. Първият — text view само за четене с атрибутиран текст и data detector за показване на съдържание. Вторият — редактируем text view с мързелив placeholder и динамична височина за форма за коментар. И двата примера използват best practices на UIKit: делегатски протокол, Auto Layout и TextKit.
Режим само за четене се активира чрез задаване на 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 }
// Зареждане на съдържание от URL и задаване на attributedText
}
}
Placeholder за UITextView не е вграден — имплементирайте го чрез UILabel над textView или чрез attributedText с проверка isEmpty. Прост подход: UILabel със сив текст, който се скрива при започване на редактиране. В textViewDidChange проверявайте наличието на текст и скривайте/показвайте placeholder. За по-елегантно решение използвайте свойството typingAttributes за задаване на цвят на въведения текст. Динамичната височина на textView се постига чрез наблюдение на contentSize и актуализиране на ограничения — това е стандартният модел за чатове и форми за коментари.
Често задавани въпроси
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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също