UITextView adalah komponen teks multi-baris UIKit, yang mewarisi UIScrollView dan mendukung pengeditan teks beratribut dengan penyisipan tautan dan gambar. Menurut dokumentasi Apple Developer (2025), UITextView menyediakan UITextViewDelegate dengan callback textViewDidChange, shouldInteractWithURL dan shouldInteractWithTextAttachment untuk menangani interaksi. Tidak seperti UITextField, UITextView mendukung pengguliran, gaya teks melalui typingAttributes dan dataDetectorTypes untuk deteksi otomatis tautan, alamat dan tanggal. Ini adalah komponen utama untuk menampilkan konten dan memasukkan teks multi-baris di aplikasi iOS.
Poin Utama
UITextView adalah komponen UIKit yang dirancang untuk menampilkan dan mengedit teks multi-baris. Tidak seperti UILabel, UITextView mendukung pemilihan teks, pengeditan, pengguliran saat melebihi ukuran dan teks beratribut. Sebagai pewaris UIScrollView, UITextView secara otomatis mengaktifkan pengguliran vertikal dan horizontal saat konten melebihi batas — ini dikonfigurasi melalui isScrollEnabled. Kelas mendukung pengeditan melalui properti isEditable: atur false untuk mode hanya-baca. UITextView bekerja dengan NSLayoutManager melalui sistem TextKit: NSTextStorage (penyimpanan teks beratribut) → NSLayoutManager (tata letak baris) → NSTextContainer (geometri area teks). Arsitektur ini memungkinkan pembuatan tata letak kustom dengan teks yang mengelilingi gambar, teks multi-kolom dan tata letak teks kompleks. UITextView digunakan untuk menampilkan artikel, deskripsi, log, komentar dan teks multi-baris apa pun di iOS.
Perbedaan antara UITextView dan UITextField jauh melampaui jumlah baris. UITextField adalah UIControl satu baris dengan dukungan placeholder, left/right view dan tombol hapus. UITextView adalah UIScrollView multi-baris dengan sistem TextKit lengkap untuk teks beratribut. UITextField tidak mendukung NSAttributedString pada level tampilan (hanya melalui attributedText dengan keterbatasan), UITextView memproses NSAttributedString sepenuhnya dengan berbagai font, gaya paragraf dan gambar tersemat. UITextField memiliki tombol hapus bawaan (clearButtonMode), UITextView tidak memilikinya — memerlukan implementasi kustom. UITextField secara otomatis mengubah ukurannya sesuai konten (intrinsicContentSize), UITextView memerlukan pengelolaan tinggi manual melalui pengamatan contentSize atau batasan Auto Layout. UITextView mendukung dataDetectorTypes (deteksi otomatis tautan), UITextField mendukungnya sejak iOS 16+. Untuk memasukkan teks multi-baris (komentar, catatan, pesan) pilih UITextView. Untuk bidang formulir (nama, email, kata sandi) gunakan UITextField.
| Kemampuan | UITextView | UITextField |
|---|---|---|
| Baris | Multi-baris | Satu baris |
| Placeholder | Tidak (kustom) | bawaan |
| Atribut teks | NSAttributedString penuh | Terbatas |
| Data Detectors | Dukungan penuh | iOS 16+ |
| Gambar inline | Melalui NSTextAttachment | Tidak didukung |
| Pengguliran | bawaan (UIScrollView) | Tidak |
| Left/Right View | Tidak | bawaan |
NSAttributedString adalah kemampuan fundamental UITextView yang membedakannya dari UITextField dan UILabel. String beratribut memungkinkan pengaturan berbagai font, warna, spasi antar baris, perataan dan tautan dalam satu teks. Properti: textView.attributedText = attributedString. Atribut kunci NSAttributedString.Key: font (.systemFont, .boldSystemFont, UIFont kustom), foregroundColor, backgroundColor, paragraphStyle (NSMutableParagraphStyle dengan lineSpacing, alignment, lineBreakMode), link (URL untuk tautan interaktif), underlineStyle, strikethroughStyle, shadow, baselineOffset, kern (spasi antar huruf). Untuk membuat attributedString gunakan init(string:, attributes:) atau NSMutableAttributedString untuk menambahkan atribut ke rentang berbeda. UITextView secara otomatis menampilkan tautan (link attribute) sebagai interaktif — saat ditekan, metode delegasi shouldInteractWithURL dipanggil. Untuk mereset atribut untuk input baru gunakan 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 adalah protokol yang mengelola pengeditan dan interaksi dengan teks. Metode utama: textViewDidBeginEditing(textView) — dipanggil saat memulai pengeditan; textViewDidEndEditing — saat selesai; textViewDidChange — setiap perubahan teks; textViewDidChangeSelection — saat perubahan pemilihan; textViewShouldInteractWithURL — saat menekan tautan (mengembalikan Bool, apakah navigasi diizinkan); textViewShouldInteractWithTextAttachment — saat menekan gambar tersemat. Untuk menangani tautan di dalam UITextView, override shouldInteractWithURL — di dalamnya Anda dapat: membuka URL di SFSafariViewController, menampilkan UIAlertController untuk konfirmasi, menangani skema URL kustom. Penting: jika textView.isEditable = true, tautan tidak dapat diklik hingga ketuk ganda — untuk tautan interaktif saat pengeditan gunakan gesture recognizers.
SFSafariViewController adalah cara standar membuka tautan di aplikasi iOS. Dalam metode shouldInteractWithURL buat SFSafariViewController dengan URL dan tampilkan secara modal atau melalui navigationController. Untuk tautan universal gunakan UIApplication.shared.open(url, options) — tetapi ini keluar dari aplikasi. Untuk melarang pembukaan tautan, kembalikan false di shouldInteractWithURL dan tangani URL sendiri.
NSTextContainer — bagian dari arsitektur TextKit, menentukan area geometris di mana teks UITextView ditampilkan. Setiap UITextView memiliki textContainer standar, dikonfigurasi melalui: textView.textContainerInset — margin teks dari batas textView (UIEdgeInsets); textView.textContainer.lineFragmentPadding — margin horizontal di dalam setiap baris; textView.textContainer.maximumNumberOfLines — batasan jumlah baris (0 = tanpa batas); textView.textContainer.exclusionPaths — array UIBezierPath untuk area yang harus dilewati teks (gambar, bentuk kustom). ExclusionPaths memungkinkan pembuatan tata letak kompleks: teks mengelilingi foto profil bundar, ikon atau kontur apa pun. Untuk ukuran dinamis UITextView amati contentSize melalui KVO atau delegasi dan perbarui batasan.
// Tinggi dinamis UITextView melalui 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 untuk membungkus gambar
let imageFrame = CGRect(x: 16, y: 100, width: 80, height: 80)
let exclusionPath = UIBezierPath(rect: imageFrame)
textView.textContainer.exclusionPaths = [exclusionPath]
dataDetectorTypes — properti UITextView yang secara otomatis mengenali dan membuat interaktif jenis data tertentu dalam teks: .link (URL, email), .phoneNumber (nomor telepon), .address (alamat), .calendarEvent (tanggal dan acara), .flightNumber (nomor penerbangan), .lookupSuggestion (saran pencarian), .trackingNumber (nomor pelacakan), .money (jumlah), .shipmentTrackingNumber, .all (semua jenis). Data Detector bekerja dengan NSDataDetector dan URL, secara otomatis menyorot data yang terdeteksi. Untuk menyesuaikan penanganan, atur dataDetectorTypes dan override shouldInteractWithURL di delegasi. Penting: dataDetectorTypes hanya berfungsi untuk URL dan phoneNumber tanpa konfigurasi tambahan — jenis lainnya mungkin memerlukan iOS 16+. Data Detector tidak bertentangan dengan link attribute di NSAttributedString — kedua mekanisme bekerja secara paralel. Untuk UITextView hanya-baca dengan konten (berita, artikel) atur dataDetectorTypes = [.link, .phoneNumber].
Mari kita lihat dua contoh praktis penggunaan UITextView di aplikasi iOS. Pertama — text view hanya-baca dengan teks beratribut dan data detector untuk menampilkan konten. Kedua — text view yang dapat diedit dengan placeholder malas dan tinggi dinamis untuk formulir komentar. Kedua contoh menggunakan praktik terbaik UIKit: protokol delegasi, Auto Layout dan TextKit.
Mode hanya-baca diaktifkan dengan mengatur isEditable = false dan isSelectable = true. Ini memungkinkan pengguna memilih teks dan menekan tautan, tetapi tidak mengedit. Atur dataDetectorTypes untuk deteksi tautan otomatis, backgroundColor = .clear untuk latar belakang transparan. Untuk menampilkan konten panjang gunakan attributedText dengan NSMutableParagraphStyle lineSpacing untuk keterbacaan. Tambahkan link attributes untuk tautan kunci dalam teks.
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 }
// Muat konten dari URL dan atur attributedText
}
}
Placeholder untuk UITextView tidak built-in — implementasikan melalui UILabel di atas textView atau melalui attributedText dengan pemeriksaan isEmpty. Pendekatan sederhana: UILabel dengan teks abu-abu yang disembunyikan saat memulai pengeditan. Di textViewDidChange periksa keberadaan teks dan sembunyikan/tampilkan placeholder. Untuk solusi yang lebih elegan gunakan properti typingAttributes untuk mengatur warna teks yang dimasukkan. Tinggi dinamis textView dicapai melalui pengamatan contentSize dan pembaruan batasan — ini adalah pola standar untuk chat dan formulir komentar.
Pertanyaan Umum
UITextView tidak memiliki placeholder built-in. Solusi standar: tambahkan UILabel dengan teks abu-abu di atas textView. Di textViewDidBeginEditing sembunyikan label, di textViewDidEndEditing tampilkan jika teks kosong. Alternatif: gunakan attributedText dengan warna abu-abu sebagai placeholder dan reset saat memulai pengeditan. Untuk solusi siap pakai gunakan perpustakaan KMPlaceholderTextView atau ReactorKit.
Atur textContainerInset = .zero dan lineFragmentPadding = 0: textView.textContainerInset = UIEdgeInsets.zero; textView.textContainer.lineFragmentPadding = 0. Tambahan: textView.contentInset = .zero. Ini akan sepenuhnya menghapus margin dari tepi textView ke teks. Perhatikan bahwa lineFragmentPadding default adalah 5.
Periksa: isSelectable = true (diperlukan untuk interaksi), dataDetectorTypes menyertakan .link, delegasi tidak mengembalikan false di shouldInteractWithURL. Jika textView.isEditable = true, tautan tidak dapat diklik dengan satu ketukan — diperlukan ketuk ganda. Untuk tautan interaktif di textView yang dapat diedit tambahkan UITapGestureRecognizer di atas textView dan tangani URL secara manual.
Atur isScrollEnabled = true dan tambahkan height constraint dengan nilai tetap. Teks yang melebihi tinggi akan digulir. Untuk UX optimal gunakan maxHeight: amati contentSize dan atur height constraint tidak lebih tinggi dari maxHeight. Saat melebihi maxHeight aktifkan scrollEnabled. Ini adalah pola standar untuk bidang input pesan dan komentar.
Gunakan NSTextAttachment: buat objek, atur image dan bounds, lalu buat NSAttributedString dari attachment dan sisipkan ke textView.attributedText. Contoh: let attachment = NSTextAttachment(); attachment.image = image; attachment.bounds = CGRect(x, y, width, height); let attributedString = NSAttributedString(attachment: attachment). Gambar akan ditampilkan inline dalam teks dan digulir bersama dengannya.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga