iOS13-Swift5富文本NSAttributedString和NSMutableAttributedString的使用

7,946 阅读3分钟

在UILabel,UITextView,UITextField中可以对其中的字符串进行更详细的设置,也就是所谓的富文本,在storyboard上可用图形化界面来设置:

把第一行的Text改成Attributed即可:

这里主要说一下如何用代码设置,大家可以对照着同时记忆。

建议大家新建个playground,可实时看效果。

基本使用

let str = "跟Lebus学iOS开发"

//因attributes字典的值为Any类型,无法用.语法,需写全类名
let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 30),
    .foregroundColor: UIColor.green
]

let attributedStr = NSAttributedString(string: str, attributes: attributes)

//textView.attributedText = attributedStr //赋给attributedText属性以显示到view上面去

最常用的就是给字串定字体和颜色,点击右边方块按钮看效果:

阴影

let str = "跟Lebus学iOS开发"

let shadow = NSShadow()
shadow.shadowColor = UIColor.red
shadow.shadowBlurRadius = 5

let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 30),
    .foregroundColor: UIColor.white,
    .shadow: shadow
]

let attributedStr = NSAttributedString(string: str, attributes: attributes)

段落(文本对齐,缩进,行距等)

let str = "跟Lebus学iOS开发"

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center //居中
paragraphStyle.firstLineHeadIndent = 5.0 //每段第一行缩进5

let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 30),
    .foregroundColor: UIColor.green,
    .paragraphStyle: paragraphStyle
]

let attributedStr = NSAttributedString(string: str, attributes: attributes)

可修改的富文本-NSMutableAttributedString

iOS开发的常用机制,如之后需对当前内容进行更改的话,都需定义为xxMutablexxx。

在这里表现为:需对当前富文本1-添加属性,2-拼接别的富文本(常用)的时候使用

1-1添加属性
let str = "跟LebusiOS开发"

let attributedStr = NSMutableAttributedString(string: str)

//range必须要加,参数分别表示从索引几开始取几个字符
attributedStr.addAttribute(
    .foregroundColor, 
    value: UIColor.green, 
    range: .init(location: 7, length: 5)
)

1-2添加多个属性
let str = "跟Lebus学iOS开发"

let attributedStr = NSMutableAttributedString(string: str)

let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.boldSystemFont(ofSize: 20),
    .backgroundColor: UIColor.black,
    .kern: 10 //字符间距
]

attributedStr.addAttributes(attributes, range: .init(location: 1, length: 5))

2-拼接别的富文本(常用于Label中不同文本的拼接)
//富文本1--定义为NSMutableAttributedString,之后才可用append方法
let attributes1: [NSAttributedString.Key: Any] = [
    .font: UIFont.boldSystemFont(ofSize: 30),
    .backgroundColor: UIColor.black
]

let attributedStr1 = NSMutableAttributedString(string: "跟Lebus", attributes: attributes1)

//富文本2--定义为普通的NSAttributedString
let attributes2: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 30)
]
let attributedStr2 = NSAttributedString(string: "\n学iOS开发", attributes: attributes2)

attributedStr1.append(attributedStr2)

解析HTML中的富文本--可解析字体,字号,颜色等

let html = """
<html>
<body>
<p style="color: blue;">我是蓝色字</p>
</body>
</html>
"""

let data = Data(html.utf8)

if let attributedString = try? NSAttributedString(
    data: data,
    options: [.documentType: NSAttributedString.DocumentType.html],
    documentAttributes: nil)
{
    //以下代码playground中没用,仅演示
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
    label.attributedText = attributedString
}

enumerateAttribute

用于从别处读取到的富文本对其再加工

//以下模拟从别处读到的文本
let sentence = "跟LebusiOS开发和macOS开发"
let regularAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12)]
let largeAttributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 24)]
let attributedSentence = NSMutableAttributedString(string: sentence, attributes: regularAttributes)

attributedSentence.setAttributes(largeAttributes, range: NSRange(location: 1, length: 5))
attributedSentence.setAttributes(largeAttributes, range: NSRange(location: 7, length: 5))
attributedSentence.setAttributes(largeAttributes, range: NSRange(location: 13, length: 7))

//再加工
attributedSentence.enumerateAttribute(.font, in: NSRange(0..<attributedSentence.length)) { value, range, stop in
    if let font = value as? UIFont {
        // 确认粗体
        if font.fontDescriptor.symbolicTraits.contains(.traitBold) {
            // 把粗体加上绿色
            attributedSentence.addAttribute(.foregroundColor, value: UIColor.green, range: range)
        }
    }
}

给富文本添加图片附件

以下代码在项目中执行才有效果,这里为方便使用系统图标演示

let attributedStr = NSMutableAttributedString(
    string: "跟Lebus学习iOS开发",
    attributes: [
        NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20),
        NSAttributedString.Key.foregroundColor: UIColor.green
    ]
)

let imageStr = NSAttributedString(
    attachment: NSTextAttachment(
        image: UIImage(systemName: "hand.thumbsup")!
    )
)

attributedStr.append(imageStr)

//textView.attributedText = attributedStr

超链接

let attributedString = NSMutableAttributedString(string: "想学习iOS吗? 点我")
attributedString.addAttribute(
    .link,
    value: "https://m.cctalk.com/inst/s9vfhehl",
    range: NSRange(location: 9, length: 2)
)

//textView.linkTextAttributes = xxx //可自定义link的样式