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. За поља форме (име, 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 шеме. Важно: ако је 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, 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 апликацијама. Први — 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође