NSAttributedString là một lớp từ framework Foundation trong iOS SDK đại diện cho một chuỗi với một tập hợp các thuộc tính định dạng được áp dụng cho các ký tự riêng lẻ hoặc phạm vi văn bản. Không giống như NSString thông thường, NSAttributedString lưu trữ không chỉ các ký tự Unicode mà còn một từ điển các thuộc tính (phông chữ, màu sắc, kerning, căn chỉnh) cho mỗi đoạn của chuỗi. Theo Tài liệu Nhà phát triển Apple (2026), NSAttributedString là nền tảng để hiển thị văn bản đã định dạng trong tất cả các thành phần UI của iOS.
Các điểm chính
NSAttributedString là một lớp cơ bản của iOS/macOS để làm việc với văn bản đã định dạng. Nó mở rộng NSString bằng cách thêm các thuộc tính vào chuỗi — một từ điển các cặp khóa-giá trị, trong đó khóa là hằng số NSAttributedStringKey (ví dụ: .font, .foregroundColor) và giá trị là đối tượng tương ứng (UIFont, UIColor). Mỗi ký tự trong chuỗi có thể có tập hợp thuộc tính riêng, cho phép định dạng hỗn hợp trong một chuỗi duy nhất.
Kiến trúc của NSAttributedString dựa trên khái niệm về các lần chạy thuộc tính (attribute runs). Nếu bạn đặt thuộc tính .font thành UIFont.boldSystemFont(ofSize: 16) cho phạm vi ký tự 0..5, tất cả các ký tự trong phạm vi đó sẽ xuất hiện dưới dạng in đậm. Các ký tự khác có thể có phông chữ khác hoặc không có thuộc tính nào. Khi hiển thị một chuỗi có thuộc tính, hệ thống UIKit hợp nhất các đặc điểm từ các phạm vi khác nhau và hiển thị văn bản đồng nhất.
NSAttributedString bất biến — sau khi tạo, các thuộc tính và nội dung của nó không thể thay đổi. Để sửa đổi, có lớp con NSMutableAttributedString, cung cấp các phương thức để thêm, xóa và thay đổi thuộc tính trong bất kỳ phạm vi nào. Sự khác biệt này quan trọng cho đa luồng: NSAttributedString bất biến an toàn cho luồng, trong khi NSMutableAttributedString thì không.
NSAttributedString hỗ trợ khoảng 40 thuộc tính tiêu chuẩn được định nghĩa trong NSAttributedStringKey. Mỗi thuộc tính ảnh hưởng đến một khía cạnh cụ thể của hình thức văn bản: phông chữ, màu sắc, vị trí, gạch chân, bóng, kerning, kiểu đoạn văn và siêu liên kết. Để đặt một thuộc tính, bạn sử dụng một hằng số NSAttributedStringKey và gán cho nó một đối tượng thuộc loại tương ứng.
| Khóa thuộc tính | Loại giá trị | Mục đích |
|---|---|---|
| .font | UIFont | Phông chữ và kích thước văn bản |
| .foregroundColor | UIColor | Màu văn bản |
| .backgroundColor | UIColor | Màu nền phía sau văn bản |
| .paragraphStyle | NSParagraphStyle | Căn chỉnh, khoảng cách dòng, thụt lề |
| .kern | NSNumber (Float) | Khoảng cách giữa các ký tự (kerning) |
| .underlineStyle | NSUnderlineStyle (Int) | Kiểu gạch chân (đơn, đôi, dày, mẫu) |
| .strikethroughStyle | NSUnderlineStyle (Int) | Kiểu gạch ngang |
| .link | NSURL | URL cho siêu liên kết tương tác |
| .shadow | NSShadow | Bóng văn bản với offset, blurRadius và màu sắc |
| .baselineOffset | NSNumber (Float) | Độ lệch văn bản so với đường cơ sở |
NSMutableParagraphStyle là một đối tượng quản lý các đặc điểm trực quan của một đoạn văn: căn chỉnh (.alignment: .left, .center, .right, .justified), khoảng cách dòng (.lineSpacing), khoảng cách đoạn văn (.paragraphSpacing), thụt lề dòng đầu tiên (.firstLineHeadIndent), thụt lề trái và phải (.headIndent, .tailIndent) và hướng văn bản (.baseWritingDirection). ParagraphStyle được áp dụng cho một phạm vi bao gồm các ký tự xuống dòng nếu cần cùng một định dạng cho toàn bộ đoạn văn.
Tạo một NSAttributedString được thực hiện thông qua một bộ khởi tạo nhận một chuỗi và một từ điển các thuộc tính. Các thuộc tính được áp dụng cho toàn bộ chuỗi. Đối với định dạng hỗn hợp (các thuộc tính khác nhau trong các phần khác nhau của chuỗi), NSMutableAttributedString được sử dụng với việc thêm thuộc tính sau đó vào các phạm vi cụ thể. Objective-C sử dụng từ điển NSAttributedStringKey: UIFont, trong khi Swift sử dụng từ điển [NSAttributedString.Key: Any] an toàn kiểu.
let plainText = "Hello, Swift!"
// Create with uniform attributes for the entire string
let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.font:
UIFont.systemFont(ofSize: 18),
NSAttributedString.Key.foregroundColor:
UIColor.darkText,
NSAttributedString.Key.kern: 1.5
]
let attributedString =
NSAttributedString(string: plainText,
attributes: attributes)
Một ví dụ minh họa định dạng đoạn văn thông qua NSMutableParagraphStyle. Đặt căn giữa, khoảng cách dòng 8 điểm, khoảng cách sau đoạn văn 12 điểm. ParagraphStyle được thêm vào từ điển thuộc tính dưới khóa .paragraphStyle. NSAttributedString sao chép paragraphStyle được truyền vào, do đó sau khi tạo chuỗi, bạn có thể sửa đổi nó mà không ảnh hưởng đến chuỗi đã tạo.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
paragraphStyle.lineSpacing = 8.0
paragraphStyle.paragraphSpacing = 12.0
paragraphStyle.firstLineHeadIndent = 20.0
let attributed = NSAttributedString(
string: "Centered paragraph with spacing",
attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
NSMutableAttributedString là một lớp con của NSAttributedString cho phép sửa đổi nội dung và thuộc tính sau khi tạo. Các phương thức chính: addAttribute(_:value:range:) để thêm một thuộc tính vào một phạm vi; addAttributes(_:range:) để thêm nhiều thuộc tính; setAttributes(_:range:) để thay thế tất cả thuộc tính trong một phạm vi; removeAttribute(_:range:) để xóa một thuộc tính; replaceCharacters(in:with:) để thay thế văn bản.
addAttribute và addAttributes thêm thuộc tính vào các thuộc tính hiện có mà không xóa các thuộc tính đã đặt. Nếu một phạm vi đã có thuộc tính với cùng khóa, giá trị của nó sẽ được thay thế. setAttributes thay thế hoàn toàn từ điển thuộc tính cho một phạm vi — tất cả các thuộc tính đã đặt trước đó đều bị xóa. Điều này quan trọng khi định dạng tuần tự một chuỗi duy nhất: addAttributes an toàn hơn vì nó không đặt lại phông chữ và màu sắc đã được thiết lập.
Phạm vi (NSRange) được chỉ định bằng cấu trúc NSRange(location: 0, length: 5). location là chỉ mục bắt đầu (dựa trên 0), length là số lượng ký tự. Nếu phạm vi vượt quá ranh giới chuỗi, NSMutableAttributedString ném ra một ngoại lệ NSRangeException. Đối với các thao tác phạm vi an toàn, hãy sử dụng các phương thức NSRange từ Foundation như NSIntersectionRange và NSUnionRange.
let attributed = NSMutableAttributedString(
string: "Bold and red text here")
// Apply bold font to first 9 characters
let boldRange = NSRange(location: 0, length: 9)
attributed.addAttribute(
NSAttributedString.Key.font,
value: UIFont.boldSystemFont(ofSize: 16),
range: boldRange)
// Apply red color to characters 13-16 ("text")
let redRange = NSRange(location: 13, length: 4)
attributed.addAttribute(
NSAttributedString.Key.foregroundColor,
value: UIColor.red,
range: redRange)
// Apply underline to the entire string
let fullRange = NSRange(location: 0,
length: attributed.length)
attributed.addAttribute(
NSAttributedString.Key.underlineStyle,
value: NSUnderlineStyle.single.rawValue,
range: fullRange)
Cách phổ biến nhất để hiển thị NSAttributedString là gán nó cho thuộc tính attributedText của UILabel. Không giống như thuộc tính text, attributedText sử dụng các thuộc tính để kết xuất, hỗ trợ định dạng hỗn hợp. Quan trọng: nếu attributedText được đặt, UILabel bỏ qua các thuộc tính font, textColor và textAlignment — tất cả các đặc điểm trực quan đến từ các thuộc tính của NSAttributedString.
let label = UILabel()
label.numberOfLines = 0
let fullText = NSMutableAttributedString(
string: "Price: $24.99 per month")
// Format "Price:" label with bold font
let priceLabelRange = NSRange(
location: 0, length: 6)
fullText.addAttribute(
NSAttributedString.Key.font,
value: UIFont.boldSystemFont(ofSize: 16),
range: priceLabelRange)
// Format "$24.99" with green color
let amountRange = NSRange(
location: 7, length: 6)
fullText.addAttribute(
NSAttributedString.Key.foregroundColor,
value: UIColor.systemGreen(),
range: amountRange)
fullText.addAttribute(
NSAttributedString.Key.font,
value: UIFont.boldSystemFont(ofSize: 22),
range: amountRange)
// Apply gray color to "per month" text
let periodRange = NSRange(
location: 14, length: 9)
fullText.addAttribute(
NSAttributedString.Key.foregroundColor,
value: UIColor.secondaryLabel,
range: periodRange)
label.attributedText = fullText
UITextView hỗ trợ các liên kết tương tác trong NSAttributedString. Thuộc tính .link với NSURL làm cho văn bản có thể nhấp được. Để xử lý các thao tác chạm, sử dụng UITextViewDelegate với phương thức textView(_:shouldInteractWith:in:interaction:). UITextView cũng hỗ trợ chọn văn bản và sử dụng UIMenuController cho các thao tác tiêu chuẩn (sao chép, tìm kiếm).
NSAttributedString hỗ trợ chuyển đổi từ HTML và RTF thông qua NSAttributedString.DocumentType. Để tải HTML, sử dụng bộ khởi tạo với tham số documentAttributes: NSAttributedString(data: htmlData, options: [.documentType: .html], documentAttributes: nil). Tương tự cho RTF: .rtf hoặc .rtfd. Cơ chế này hữu ích để hiển thị nội dung HTML mà không cần WebView.
Để xuất sang HTML, sử dụng phương thức data(from:documentAttributes:) với một phạm vi và loại tài liệu. Xuất HTML: try attributedString.data(from: fullRange, documentAttributes: [.documentType: .html]). Dữ liệu kết quả có thể được lưu vào tệp, gửi đến máy chủ hoặc hiển thị trong WebView. Trong quá trình xuất, phông chữ, màu sắc, căn chỉnh, danh sách — tất cả các thuộc tính định dạng — được chuyển đổi thành kiểu CSS.
Hỗ trợ RTF đặc biệt phù hợp cho các ứng dụng macOS, nơi RTF là định dạng văn bản phong phú tiêu chuẩn. iOS cũng hỗ trợ đọc và ghi RTF nhưng không sử dụng nó làm định dạng chính. Sự khác biệt giữa RTF và RTFD: RTFD bao gồm các tài nguyên nhúng (hình ảnh) được đóng gói trong một thư mục. NSAttributedString có thể xử lý cả hai định dạng thông qua một giao diện duy nhất.
let htmlString = "<p><b>Bold<\/b> and <i>italic<\/i><\/p>"
guard let htmlData = htmlString.data(
using: String.Encoding.utf8) else { return }
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
NSAttributedString.DocumentReadingOptionKey.documentType:
NSAttributedString.DocumentType.html
]
let attributedFromHTML =
try? NSAttributedString(
data: htmlData,
options: options,
documentAttributes: nil)
Câu hỏi thường gặp
NSString chỉ lưu trữ một chuỗi các ký tự Unicode mà không có bất kỳ thông tin định dạng nào. NSAttributedString lưu trữ các ký tự và cho mỗi phạm vi con chứa một từ điển các thuộc tính (phông chữ, màu sắc, kiểu). Khi hiển thị, UIKit sử dụng các thuộc tính này để kết xuất, tạo văn bản đã định dạng.
Lý do phổ biến nhất là sử dụng thuộc tính text thay vì attributedText. Khi gán qua text, tất cả các thuộc tính đều bị bỏ qua. Lý do thứ hai: sau khi đặt attributedText, bạn thay đổi font, textColor hoặc textAlignment của UILabel — những thay đổi này đặt lại attributedText. Chỉ sử dụng attributedText cho văn bản đã định dạng.
Tạo một NSMutableAttributedString và gọi addAttribute(.font, value: boldFont, range: boldRange) cho mỗi đoạn có phông chữ khác nhau. Mỗi lần gọi chỉ áp dụng thuộc tính cho phạm vi được chỉ định. Các ký tự còn lại giữ phông chữ tiêu chuẩn hoặc phông chữ khác đã được đặt trước đó. Bằng cách này, các lần chạy thuộc tính với các phông chữ khác nhau được tạo ra.
Có, NSAttributedString xử lý chính xác văn bản nhiều dòng, bao gồm các ký tự xuống dòng ( ). UITextView và UILabel (với numberOfLines = 0) tự động xuống dòng văn bản. NSMutableParagraphStyle quản lý khoảng cách dòng, thụt lề và căn chỉnh cho mỗi đoạn văn một cách độc lập.
Sử dụng NSMutableAttributedString với thuộc tính .foregroundColor cho mỗi phạm vi màu. Cho văn bản màu đỏ: addAttribute(.foregroundColor, value: UIColor.red, range: firstRange). Cho màu xanh: addAttribute(.foregroundColor, value: UIColor.blue, range: secondRange). Màu sắc sẽ chỉ được áp dụng cho các phạm vi ký tự được chỉ định.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm