UITextView: шта је то, вишередни унос и принцип рада

Аутор: IT Sectr Објављено: 2026-07-07 Време читања: 8 мин

UITextView је вишередни текст компонента UIKit, наследник UIScrollView и подржава уређивање атрибуираног текста са уградњом линкова и слика. Према документацији Apple Developer (2025), UITextView пружа UITextViewDelegate са callback-има textViewDidChange, shouldInteractWithURL и shouldInteractWithTextAttachment за обраду интеракција. За разлику од UITextField, UITextView подржава померање, текстуалне стилове кроз typingAttributes и dataDetectorTypes за аутоматско откривање линкова, адреса и датума. Ово је основна компонента за приказ садржаја и унос вишередног текста у iOS апликацијама.

Главно

  • UITextView — вишередно текстуално поље UIKit, наследник UIScrollView са подршком за уређивање
  • NSAttributedString — подршка за атрибуирани текст: фонтови, боје, размаци између редова, линкови
  • UITextViewDelegate — управљање кроз textViewDidChange, shouldInteractWithURL, didBeginEditing
  • Data Detector Types — аутоматско откривање линкова, адреса, датума, телефонских бројева у тексту
  • Text Container — систем textContainer, exclusionPaths и lineFragmentPadding за прилагођени изглед

Шта је UITextView

UITextView је компонента UIKit намењена за приказ и уређивање вишередног текста. За разлику од UILabel, UITextView подржава избор текста, уређивање, померање при прекорачењу димензија и атрибуирани текст. Као наследник UIScrollView, UITextView аутоматски укључује вертикално и хоризонтално померање при прекорачењу садржаја — ово се подешава кроз isScrollEnabled. Класа подржава уређивање кроз својство isEditable: поставите false за режим само за читање. UITextView ради са NSLayoutManager кроз TextKit систем: NSTextStorage (чување атрибуираног текста) → NSLayoutManager (распоред редова) → NSTextContainer (геометрија области текста). Ова архитектура омогућава креирање прилагођеног изгледа са обавијањем текста око слика, вишеколонски текст и сложене текстуалне распореде. UITextView се користи за приказ чланака, описа, логова, коментара и било ког вишередног текста у iOS.

UITextView vs UITextField: кључне разлике

Разлика између 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.

МогућностUITextViewUITextField
РедовиВишередниЈедноредни
PlaceholderНема (прилагођени)Уграђени
Атрибути текстаПотпун NSAttributedStringОграничен
Data DetectorsПотпуна подршкаiOS 16+
Слике inlineКроз NSTextAttachmentНе подржава се
ПомерањеУграђено (UIScrollView)Нема
Left/Right ViewНемаУграђени

NSAttributedString и форматирање текста

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.

swift
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 и обрада линкова

UITextViewDelegate је протокол који управља уређивањем и интеракцијом са текстом. Главне методе: textViewDidBeginEditing(textView) — позива се при почетку уређивања; textViewDidEndEditing — при завршетку; textViewDidChange — при свакој промени текста; textViewDidChangeSelection — при промени избора; textViewShouldInteractWithURL — при клику на линк (враћа Bool, да ли је прелаз дозвољен); textViewShouldInteractWithTextAttachment — при клику на уграђену слику. За обраду линкова унутар UITextView преопишите shouldInteractWithURL — у њему можете: отворити URL у SFSafariViewController, приказати UIAlertController за потврду, обрадити прилагођене URL шеме. Важно: ако је textView.isEditable = true, линкови постају недоступни за клик до двоструког тапа — за интерактивне линкове при уређивању користите gesture recognizers.

Обрада линкова кроз SFSafariViewController

SFSafariViewController — стандардни начин отварања линкова у iOS апликацијама. У методи shouldInteractWithURL креирајте SFSafariViewController са URL и прикажите га модално или кроз navigationController. За универзалне линкове користите UIApplication.shared.open(url, options) — али ово излази из апликације. За забрану отварања линкова вратите false у shouldInteractWithURL и обрадите URL самостално.

Систем Text Container: маргине и exclusionPaths

NSTextContainer — део архитектуре TextKit, који одређује геометријску област у којој се приказује текст UITextView. Сваки UITextView има стандардни textContainer, подесив кроз: textView.textContainerInset — маргине текста од граница textView (UIEdgeInsets); textView.textContainer.lineFragmentPadding — хоризонтална маргина унутар сваког реда; textView.textContainer.maximumNumberOfLines — ограничење броја редова (0 = без лимита); textView.textContainer.exclusionPaths — низ UIBezierPath за области које текст треба да обилази (слике, прилагођени облици). ExclusionPaths омогућавају креирање сложеног изгледа: текст обилази округлу профилну слику, икону или било коју произвољну контуру. За динамичку величину UITextView пратите contentSize кроз KVO или делегата и ажурирајте ограничења.

swift
// Динамичка висина 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]

Data Detector Types: аутоматско откривање података

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].

  • .link — URL, email адресе; приказују се као плави линкови
  • .phoneNumber — телефонски бројеви; клик показује Call акцију
  • .address — поштанске адресе; клик отвара Maps
  • .calendarEvent — датуми и време; клик креира догађај календара
  • .flightNumber — бројеви летова (iOS 16+); брза провера лета

Примери кода са UITextView

Размотримо два практична примера коришћења UITextView у iOS апликацијама. Први — text view само за читање са атрибуираним текстом и data detector за приказ садржаја. Други — уређиви text view са лењим placeholder и динамичком висином за форму коментара. Оба примера користе best practices UIKit: делегатски протокол, Auto Layout и TextKit.

UITextView само за читање са садржајем и линковима

Режим само за читање се укључује постављањем isEditable = false и isSelectable = true. Ово омогућава кориснику да бира текст и кликће на линкове, али не и да уређује. Поставите dataDetectorTypes за аутоматско откривање линкова, backgroundColor = .clear за провидан фон. За приказ дугог садржаја користите attributedText са NSMutableParagraphStyle lineSpacing за читљивост. Додајте link attributes за кључне линкове у тексту.

swift
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
    }
}

Уређиви UITextView са placeholder

Placeholder за UITextView није уграђен — имплементирајте га кроз UILabel изнад textView или кроз attributedText са провером isEmpty. Једноставан приступ: UILabel са сивим текстом који се сакрива при почетку уређивања. У textViewDidChange проверавајте присуство текста и сакривајте/приказујте placeholder. За елегантније решење користите својство typingAttributes за постављање боје унетог текста. Динамичка висина textView се постиже праћењем contentSize и ажурирањем ограничења — ово је стандардни образац за четове и форме коментара.

Често постављана питања

Како додати placeholder у UITextView?

UITextView нема уграђени placeholder. Стандардно решење: додајте UILabel са сивим текстом изнад textView. У textViewDidBeginEditing сакривајте label, у textViewDidEndEditing приказујте ако је текст празан. Алтернативно: користите attributedText са сивом бојом као placeholder и ресетујте га при почетку уређивања. За готово решење користите библиотеку KMPlaceholderTextView или ReactorKit.

Како уклонити маргине у UITextView?

Поставите textContainerInset = .zero и lineFragmentPadding = 0: textView.textContainerInset = UIEdgeInsets.zero; textView.textContainer.lineFragmentPadding = 0. Додатно: textView.contentInset = .zero. Ово ће потпуно уклонити маргине од ивица textView до текста. Имајте у виду да је lineFragmentPadding подразумевано 5.

Зашто UITextView не отвара линкове?

Проверите: isSelectable = true (неопходно за интеракцију), dataDetectorTypes укључује .link, делегат не враћа false у shouldInteractWithURL. Ако је textView.isEditable = true, линкови су недоступни за један клик — потребан је двоструки тап. За интерактивне линкове у уређивом textView додајте UITapGestureRecognizer изнад textView и обрадите URL ручно.

Како направити UITextView фиксне висине са померањем?

Поставите isScrollEnabled = true и додајте height constraint са фиксном вредношћу. Текст који прелази висину ће се померати. За оптимални UX користите maxHeight: пратите contentSize и постављајте height constraint не већи од maxHeight. При прекорачењу maxHeight укључите scrollEnabled. Ово је стандардни образац за поља за унос порука и коментара.

Како уметнути слику у UITextView?

Користите 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 у тексту и помераће се заједно са њим.

Закључак

  • UITextView — вишередни текст компонента UIKit, наследник UIScrollView са TextKit подршком
  • NSAttributedString — кључна могућност за форматирање фонтова, боја, линкова и пасуса
  • UITextViewDelegate — управљање уређивањем и обрада кликова на линкове и прилоге
  • Data Detector Types — аутоматско откривање URL, телефона, адреса и датума кроз NSDataDetector
  • Text Container — систем са exclusionPaths, lineFragmentPadding и textContainerInset за изглед
  • Placeholder — није уграђен, имплементира се кроз UILabel или attributedText са сивом бојом
  • Dynamic height — праћење contentSize и ажурирање ограничења за аутоматску висину
  • UITextView се разликује од UITextField подршком за вишередност, атрибуте, померање и data detectors

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође