iOS 展示富文本/長文本(如部落格文章)時,選擇 UILabel 還是 UITextView,取決於交互需求而非單純文本長度。
| 需求 | 推薦控件 | 關鍵配置 |
|---|---|---|
| 純展示、不可編輯、不可選中、無鏈接檢測 | UILabel | numberOfLines = 0、lineBreakMode = .byWordWrapping、放入 UIScrollView |
| 需用戶選中複製、長按選單、鏈接/電話/日期檢測 | UITextView | isEditable = false、isSelectable = true、dataDetectorTypes |
| 需用戶編輯輸入 | UITextView | isEditable = true |
| 極長文本(超過 1 萬字)、高性能滾動 | UITextView 或 Core Text / TextKit 2 自定義佈局 | 分頁加載、異步佈局 |
| 富文本(圖文混排、自定義屬性) | UITextView (TextKit) 或 UILabel (NSAttributedString) | iOS 16+ TextKit 2 首選 |
// 代碼創建
let label = UILabel()
label.numberOfLines = 0 // 關鍵:不限制行數
label.lineBreakMode = .byWordWrapping
label.attributedText = attributedString // 支援富文本
label.font = .systemFont(ofSize: 16)
label.textColor = .label
// 放入 ScrollView(或 UITableViewCell 自適應高度)
scrollView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 16),
label.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 16),
label.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -16),
label.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -16),
label.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -32)
])
let textView = UITextView()
textView.isEditable = false // 禁止編輯
textView.isSelectable = true // 允許選中複製
textView.isScrollEnabled = false // 關鍵:禁用內部滾動,交給外部 ScrollView 或 TableView 自適應
textView.dataDetectorTypes = [.link, .phoneNumber, .address, .calendarEvent] // 自動檢測鏈接
textView.attributedText = attributedString
textView.font = .systemFont(ofSize: 16)
textView.textColor = .label
textView.textContainerInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
textView.textContainer.lineFragmentPadding = 0 // 去除預設左右內邊距
| 指標 | UILabel | UITextView |
|---|---|---|
| 佈局速度 | 極快(Core Graphics 直接繪製) | 較慢(TextKit 佈局引擎) |
| 記憶體佔用 | 低 | 高(佈局管理器、文本容器、存儲管理器) |
| 滾動幀率 | 需配合 ScrollView,Cell 自適應高度需預計算 | 原生支援滾動,但禁用內部滾動時同 UILabel |
| 富文本支援 | NSAttributedString 完整支援 | NSAttributedString + TextKit 進階排版 |
| iOS 16+ 新特性 | 無特殊更新 | TextKit 2:非同步佈局、更好性能、SwiftUI 整合 |
UILabel + UIScrollView / 自適應 UITableViewCell。UITextView + dataDetectorTypes。UITextView + isEditable = true。UITextView + TextKit 2 非同步佈局、或 WKWebView 渲染 HTML。
// SwiftUI 統一文本展示
Text(attributedString) // iOS 15+ 支援 AttributedString
.font(.system(size: 16))
.textSelection(.enabled) // iOS 15+ 允許選中複製
// 自動適配動態類型、深色模式、無障礙
總結:無交互用 UILabel,有選中/鏈接/編輯用 UITextView。別為「文本長」而選 UITextView——UILabel 配合 numberOfLines = 0 完美支援任意長度。