UITextView je víceřádková textová komponenta UIKit, dědící z UIScrollView a podporující úpravy atributového textu s vkládáním odkazů a obrázků. Podle dokumentace Apple Developer (2025) poskytuje UITextView UITextViewDelegate s callbacky textViewDidChange, shouldInteractWithURL a shouldInteractWithTextAttachment pro zpracování interakcí. Na rozdíl od UITextField podporuje UITextView rolování, textové styly pomocí typingAttributes a dataDetectorTypes pro automatickou detekci odkazů, adres a dat. Toto je hlavní komponenta pro zobrazení obsahu a vstup víceřádkového textu v iOS aplikacích.
Hlavní body
UITextView je komponenta UIKit určená pro zobrazení a úpravu víceřádkového textu. Na rozdíl od UILabel podporuje UITextView výběr textu, úpravy, rolování při překročení rozměrů a atributový text. Jako dědic UIScrollView automaticky zapíná vertikální a horizontální rolování při překročení obsahu — to se konfiguruje pomocí isScrollEnabled. Třída podporuje úpravy pomocí vlastnosti isEditable: nastavte false pro režim pouze pro čtení. UITextView pracuje s NSLayoutManager prostřednictvím systému TextKit: NSTextStorage (ukládání atributového textu) → NSLayoutManager (rozvržení řádků) → NSTextContainer (geometrie oblasti textu). Tato architektura umožňuje vytvářet vlastní rozvržení s obtékáním textu kolem obrázků, vícesloupcový text a složité textové rozvržení. UITextView se používá pro zobrazení článků, popisů, logů, komentářů a libovolného víceřádkového textu v iOS.
Rozdíl mezi UITextView a UITextField zdaleka přesahuje počet řádků. UITextField je jednořádkový UIControl s podporou placeholder, left/right view a tlačítka pro vymazání. UITextView je víceřádkový UIScrollView s plnohodnotným systémem TextKit pro atributový text. UITextField nepodporuje NSAttributedString na úrovni zobrazení (pouze přes attributedText s omezeními), UITextView plně zpracovává NSAttributedString s různými písmy, styly odstavců a vloženými obrázky. UITextField má vestavěné tlačítko pro vymazání (clearButtonMode), UITextView ho nemá — vyžaduje vlastní implementaci. UITextField automaticky mění svou velikost podle obsahu (intrinsicContentSize), UITextView vyžaduje ruční správu výšky pomocí sledování contentSize nebo omezení Auto Layout. UITextView podporuje dataDetectorTypes (automatická detekce odkazů), UITextField je podporuje od iOS 16+. Pro vstup víceřádkového textu (komentáře, poznámky, zprávy) zvolte UITextView. Pro pole formuláře (jméno, email, heslo) použijte UITextField.
| Možnost | UITextView | UITextField |
|---|---|---|
| Řádky | Víceřádkový | Jednořádkový |
| Placeholder | Ne (vlastní) | Vestavěný |
| Atributy textu | Plný NSAttributedString | Omezený |
| Data Detectors | Plná podpora | iOS 16+ |
| Obrázky inline | Přes NSTextAttachment | Nepodporováno |
| Rolování | Vestavěné (UIScrollView) | Ne |
| Left/Right View | Ne | Vestavěné |
NSAttributedString je základní možnost UITextView, která ho odlišuje od UITextField a UILabel. Atributový řetězec umožňuje nastavit různá písma, barvy, řádkování, zarovnání a odkazy v rámci jednoho textu. Vlastnosti: textView.attributedText = attributedString. Klíčové atributy NSAttributedString.Key: font (.systemFont, .boldSystemFont, vlastní UIFont), foregroundColor, backgroundColor, paragraphStyle (NSMutableParagraphStyle s lineSpacing, alignment, lineBreakMode), link (URL pro interaktivní odkazy), underlineStyle, strikethroughStyle, shadow, baselineOffset, kern (mezera mezi znaky). Pro vytvoření attributedString použijte init(string:, attributes:) nebo NSMutableAttributedString pro přidání atributů do různých rozsahů. UITextView automaticky zobrazuje odkazy (link attribute) jako interaktivní — při stisknutí se zavolá delegátní metoda shouldInteractWithURL. Pro resetování atributů pro nový vstup použijte 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 je protokol, který spravuje úpravy a interakci s textem. Hlavní metody: textViewDidBeginEditing(textView) — volá se při zahájení úprav; textViewDidEndEditing — při ukončení; textViewDidChange — při každé změně textu; textViewDidChangeSelection — při změně výběru; textViewShouldInteractWithURL — při kliknutí na odkaz (vrací Bool, zda je navigace povolena); textViewShouldInteractWithTextAttachment — při kliknutí na vložený obrázek. Pro zpracování odkazů uvnitř UITextView přepište shouldInteractWithURL — v něm můžete: otevřít URL v SFSafariViewController, zobrazit UIAlertController pro potvrzení, zpracovat vlastní URL schémata. Důležité: pokud je textView.isEditable = true, odkazy nejsou k dispozici pro kliknutí do dvojitého klepnutí — pro interaktivní odkazy při úpravách použijte gesture recognizers.
SFSafariViewController je standardní způsob otevírání odkazů v iOS aplikacích. V metodě shouldInteractWithURL vytvořte SFSafariViewController s URL a zobrazte jej modálně nebo přes navigationController. Pro univerzální odkazy použijte UIApplication.shared.open(url, options) — ale to opouští aplikaci. Pro zakázání otevírání odkazů vraťte false v shouldInteractWithURL a zpracujte URL sami.
NSTextContainer — část architektury TextKit, která určuje geometrickou oblast, ve které se zobrazuje text UITextView. Každý UITextView má standardní textContainer, konfigurovatelný pomocí: textView.textContainerInset — okraje textu od hranic textView (UIEdgeInsets); textView.textContainer.lineFragmentPadding — horizontální okraj uvnitř každého řádku; textView.textContainer.maximumNumberOfLines — omezení počtu řádků (0 = bez limitu); textView.textContainer.exclusionPaths — pole UIBezierPath pro oblasti, které má text obtékat (obrázky, vlastní tvary). ExclusionPaths umožňují vytvářet složité rozvržení: text obtéká kulatý profilový obrázek, ikonu nebo libovolný kontur. Pro dynamickou velikost UITextView sledujte contentSize přes KVO nebo delegáta a aktualizujte omezení.
// Dynamická výška UITextView pomocí 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 pro obtékání obrázků
let imageFrame = CGRect(x: 16, y: 100, width: 80, height: 80)
let exclusionPath = UIBezierPath(rect: imageFrame)
textView.textContainer.exclusionPaths = [exclusionPath]
dataDetectorTypes — vlastnost UITextView, která automaticky rozpoznává a činí interaktivními určité typy dat v textu: .link (URL, email), .phoneNumber (telefonní čísla), .address (adresy), .calendarEvent (data a události), .flightNumber (čísla letů), .lookupSuggestion (vyhledávací návrhy), .trackingNumber (sledovací čísla), .money (částky), .shipmentTrackingNumber, .all (všechny typy). Data Detector pracuje s NSDataDetector a URL, automaticky zvýrazňuje detekovaná data. Pro přizpůsobení zpracování nastavte dataDetectorTypes a přepište shouldInteractWithURL v delegátovi. Důležité: dataDetectorTypes funguje pouze pro URL a phoneNumber bez další konfigurace — ostatní typy mohou vyžadovat iOS 16+. Data Detector není v konfliktu s link attribute v NSAttributedString — oba mechanismy pracují paralelně. Pro UITextView pouze pro čtení s obsahem (zprávy, články) nastavte dataDetectorTypes = [.link, .phoneNumber].
Podívejme se na dva praktické příklady použití UITextView v iOS aplikacích. První — text view pouze pro čtení s atributovým textem a data detectorem pro zobrazení obsahu. Druhý — upravitelný text view s líným placeholderem a dynamickou výškou pro formulář komentáře. Oba příklady používají best practices UIKit: delegátní protokol, Auto Layout a TextKit.
Režim pouze pro čtení se aktivuje nastavením isEditable = false a isSelectable = true. To umožňuje uživateli vybírat text a klikat na odkazy, ale neupravovat. Nastavte dataDetectorTypes pro automatickou detekci odkazů, backgroundColor = .clear pro průhledné pozadí. Pro zobrazení dlouhého obsahu použijte attributedText s NSMutableParagraphStyle lineSpacing pro čitelnost. Přidejte link attributes pro klíčové odkazy v textu.
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 }
// Načíst obsah z URL a nastavit attributedText
}
}
Placeholder pro UITextView není vestavěný — implementujte ho přes UILabel nad textView nebo přes attributedText s kontrolou isEmpty. Jednoduchý přístup: UILabel s šedým textem, který se skrývá při zahájení úprav. V textViewDidChange kontrolujte přítomnost textu a skrývejte/zobrazujte placeholder. Pro elegantnější řešení použijte vlastnost typingAttributes pro nastavení barvy vstupního textu. Dynamické výšky textView se dosahuje sledováním contentSize a aktualizací omezení — to je standardní vzor pro chaty a formuláře komentářů.
Často kladené otázky
UITextView nemá vestavěný placeholder. Standardní řešení: přidejte UILabel s šedým textem nad textView. V textViewDidBeginEditing skryjte label, v textViewDidEndEditing zobrazte, pokud je text prázdný. Alternativně: použijte attributedText s šedou barvou jako placeholder a resetujte při zahájení úprav. Pro hotové řešení použijte knihovnu KMPlaceholderTextView nebo ReactorKit.
Nastavte textContainerInset = .zero a lineFragmentPadding = 0: textView.textContainerInset = UIEdgeInsets.zero; textView.textContainer.lineFragmentPadding = 0. Doplňkově: textView.contentInset = .zero. To zcela odstraní okraje od okrajů textView k textu. Mějte na paměti, že lineFragmentPadding je ve výchozím nastavení 5.
Zkontrolujte: isSelectable = true (nutné pro interakci), dataDetectorTypes zahrnuje .link, delegát nevrací false v shouldInteractWithURL. Pokud je textView.isEditable = true, odkazy nejsou k dispozici pro jedno klepnutí — vyžaduje se dvojité klepnutí. Pro interaktivní odkazy v upravitelném textView přidejte UITapGestureRecognizer nad textView a zpracujte URL ručně.
Nastavte isScrollEnabled = true a přidejte height constraint s pevnou hodnotou. Text překračující výšku bude rolován. Pro optimální UX použijte maxHeight: sledujte contentSize a nastavte height constraint ne vyšší než maxHeight. Při překročení maxHeight zapněte scrollEnabled. Toto je standardní vzor pro pole pro vstup zpráv a komentářů.
Použijte NSTextAttachment: vytvořte objekt, nastavte image a bounds, poté vytvořte NSAttributedString z attachment a vložte do textView.attributedText. Příklad: let attachment = NSTextAttachment(); attachment.image = image; attachment.bounds = CGRect(x, y, width, height); let attributedString = NSAttributedString(attachment: attachment). Obrázek se zobrazí inline v textu a bude rolován spolu s ním.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také