利用 AttributedString 或 NSAttributedString 實現多種樣式組合的文字
開發 iOS App 時,我們時常會看到多種樣式組合的文字,比方下圖 IG App 紅色框框的文字區塊,人名 anwei20 跟終於 … 的文字是不同的樣式。
利用 AttributedString 或 NSAttributedString 將可實現多種樣式組合的文字效果,以下彼得潘將以戴佩妮創作的好聽歌曲天花版的星星
說明。
從 Xcode playground 實驗 AttributedString
透過 iOS 15 推出的 AttributedString,我們可以實現多種樣式組合的文字效果。以下為 Xcode playground 的程式範例。
import UIKit
var content = AttributedString()
var name = AttributedString("anwei20 ")
name.font = .boldSystemFont(ofSize: 30)
name.foregroundColor = UIColor.black
content += name
var message = AttributedString("戴佩妮創作的天花版的星星\n")
message.font = .systemFont(ofSize: 18)
message.foregroundColor = UIColor.gray
content += message
var lyrics = AttributedString("看你從没看過的風景 躲没躲過的大雨 創造一個天晴 避開你最討厭的擁擠 你最害怕的猜疑 好好喘口氣")
lyrics.font = .systemFont(ofSize: 14)
lyrics.foregroundColor = UIColor.systemPink
lyrics.backgroundColor = UIColor.cyan
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 5
lyrics.paragraphStyle = paragraphStyle
content += lyrics
let label = UILabel()
label.attributedText = NSAttributedString(content)
label.numberOfLines = 0
let size = label.sizeThatFits(CGSize(width: 300, height: 0))
label.frame.size = size
label.backgroundColor = .white
label
說明
message.foregroundColor = UIColor.gray
UIColor.gray 如果要省略成 .gray,可改成 message.uiKit.foregroundColor
,讓程式知道我們指的是 UIKit 的顏色,不是 SwiftUI 的顏色。
label.attributedText = NSAttributedString(content)
由於 attributedText 的型別是 NSAttributedString,因此我們要從型別AttributedString 的 content 生成 NSAttributedString,才能存入 attributedText。
接下來讓我們搭配 storyboard 設計的 App 畫面,實驗 AttributedString & NSAttributedString 組合文字的效果。
storyboard 的畫面設計
iOS 15 以上: 使用 AttributedString
透過 AttributedString 的各種屬性設定文字樣式,比方字體,文字顏色,背景顏色,行距等。
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
var content = AttributedString()
var name = AttributedString("anwei20 ")
name.font = .boldSystemFont(ofSize: 30)
name.foregroundColor = UIColor.black
content += name
var message = AttributedString("戴佩妮創作的天花版的星星\n")
message.font = .systemFont(ofSize: 18)
message.foregroundColor = UIColor.gray
content += message
var lyrics = AttributedString("看你從没看過的風景 躲没躲過的大雨 創造一個天晴 避開你最討厭的擁擠 你最害怕的猜疑 好好喘口氣")
lyrics.font = .systemFont(ofSize: 14)
lyrics.foregroundColor = UIColor.systemPink
lyrics.backgroundColor = UIColor.cyan
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 5
lyrics.paragraphStyle = paragraphStyle
content += lyrics
label.attributedText = NSAttributedString(content)
}
}
當 AttributedString 的文字有不同大小時,預設將對齊文字底部,因此上圖的 anwei20
& 戴佩妮創作的天花版的星星
底部對齊。
不過我們也可以透過 baselineOffset 微調整對齊,比方以下例子將讓戴佩妮創作的天花版的星星
向上移動,實現 anwei20
& 戴佩妮創作的天花版的星星
置中對齊的效果。
var message = AttributedString("戴佩妮創作的天花版的星星\n")
message.font = .systemFont(ofSize: 18)
message.foregroundColor = UIColor.gray
message.baselineOffset = 4
舊版: 使用 NSAttributedString
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let content = NSMutableAttributedString()
let name = NSMutableAttributedString(string: "anwei20 ", attributes: [
.font: UIFont.boldSystemFont(ofSize: 30),
.foregroundColor: UIColor.black
])
content.append(name)
let message = NSMutableAttributedString(string: "戴佩妮創作的天花版的星星\n", attributes: [
.font: UIFont.systemFont(ofSize: 18),
.foregroundColor: UIColor.gray
])
content.append(message)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 5
let lyrics = NSMutableAttributedString(string: "看你從没看過的風景 躲没躲過的大雨 創造一個天晴 避開你最討厭的擁擠 你最害怕的猜疑 好好喘口氣", attributes: [
.font: UIFont.systemFont(ofSize: 14),
.foregroundColor: UIColor.systemPink,
.backgroundColor: UIColor.cyan,
.paragraphStyle: paragraphStyle
])
content.append(lyrics)
label.attributedText = content
}
}
當 NSMutableAttributedString 的文字有不同大小時,預設將對齊文字底部,因此上圖的 anwei20
& 戴佩妮創作的天花版的星星
底部對齊。
不過我們也可以透過 baselineOffset 微調整對齊,比方以下例子將讓戴佩妮創作的天花版的星星
向上移動,實現 anwei20
& 戴佩妮創作的天花版的星星
置中對齊的效果。
let message = NSMutableAttributedString(string: "戴佩妮創作的天花版的星星\n", attributes: [
.font: UIFont.systemFont(ofSize: 18),
.foregroundColor: UIColor.gray,
.baselineOffset: 4
])