常规Swift字符串对于存储纯文本来说已经足够,但如果你需要格式,图片,或者互动时,就要用到NSAttributedString。它是一个基础多合一字符串处理类,在iOS的很多地方都会用到,还经常和UILabel 与UITextView(它们都能直接接收属性字符串(attributed string))共同使用。
本文中我会给出一些NSAttributedString案例,展示NSAttributedString的功能,包括:手动创建字符串,添加列举属性,添加链接和图片等等。所有示例代码都可以在Swift playground上使用。因为Xcode可以预览字符串的样子,它很适合实验我们的属性字符串。
创建属性字符串(attributed string)
让我们从最基础的属性字符串开始:带有常规字符串,没有特别格式。
let quote = "Haters gonna hate"
let attributedQuote = NSAttributedString(string: quote)
在playground运行时,点击attributedQuote的预览键,就可以预览它了。因为还没有应用任何格式,它看起来就和普通字符串一样。
如果换成下面的:
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
我们要求文本渲染成72号大小,预览中也会看起来更大
字符串的样子会受到添加属性的影响,比如下例,文本就会被变成红色:
let font = UIFont.systemFont(ofSize: 72)
let attributes: [NSAttributedStringKey: Any] = [
.font: font,
.foregroundColor: UIColor.red,
]
而下面的代码会让文本变成白色,并有红色的光效
let font = UIFont.systemFont(ofSize: 72)
let shadow = NSShadow()
shadow.shadowColor = UIColor.red
shadow.shadowBlurRadius = 5
let attributes: [NSAttributedStringKey: Any] = [
.font: font,
.foregroundColor: UIColor.white,
.shadow: shadow
]
如果你想进行段落设置,比如文本对齐,首行缩进,行距等等,需要用到一个独立的类型——NSMutableParagraphStyle。下面就是应用了段落格式,让文本居中,并且每段的首行缩进5点。
let font = UIFont.systemFont(ofSize: 72)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.firstLineHeadIndent = 5.0
let attributes: [NSAttributedStringKey: Any] = [
.font: font,
.foregroundColor: UIColor.blue,
.paragraphStyle: paragraphStyle
]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
修改已存在的属性字符串
之前提到的都是从头开始创建一个属性字符串,但有时我们只是想修改一个已存在的。比如想把部分文本加粗。
那么还是从我们的基础字符串开始:
let quote = "Haters gonna hate"
let attributedQuote = NSMutableAttributedString(string: quote)
注意现在用到了NSMutableAttributedString,它是一个可以修改的属性字符串。由于类的特性,即使用let声明为常量,我们依旧可以修改这个对象。
如果你想让“gonna”变为红色,需要对这个属性字符串使用addAttribute()方法:
attributedQuote.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: 7, length: 5))
上例还用到了NSRange指定了字符串范围,这一项是必须要有的。
如果你想同时添加多属性,则要使用addAttributes,它使用和之前一样的字典法。下例中就对“Haters”一词应用了绿背景色和10点的字母间距。
let attributes: [NSAttributedStringKey: Any] = [.backgroundColor: UIColor.green, NSAttributedStringKey.kern: 10]
attributedQuote.addAttributes(attributes, range: NSRange(location: 0, length: 6))
虽然这个方法简单又高效,但我还是觉得创建多个独立属性字符串再合并到一起的方法更实用。尽管我的方法有点慢,占用内存更多,不过对于复杂字符串设计很好用。
完整的代码就是这样的:
let quote = "Haters gonna hate"
let firstAttributes: [NSAttributedStringKey: Any] = [.backgroundColor: UIColor.green, NSAttributedStringKey.kern: 10]
let secondAttributes = [NSAttributedStringKey.foregroundColor: UIColor.red]
let firstString = NSMutableAttributedString(string: "Haters ", attributes: firstAttributes)
let secondString = NSAttributedString(string: "gonna ", attributes: secondAttributes)
let thirdString = NSAttributedString(string: "hate")
firstString.append(secondString)
firstString.append(thirdString)
这种方法把工作分成了简单的小块,这意味着我可以通过搭配混合不同函数构成新的属性字符串。
从HTML加载属性字符串
通过iOS对一些HTML进行语法分析也可以创建属性字符串。尽管只能支持一部分类型,但对于处理字体字号或者颜色来说已经足够了。
比如我们可以定义HTML使用内联CSS,让一个段落变成蓝色:
let html = """
This is blue!
"""
之后把它转化成数据实例,这样就可以读取为属性字符串了,
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
0
最后,可以把这个数据加载到一个NSAttributedString,并告知它我们在使用HTML的文件类型。
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
1
属性枚举
如果你有一个别人制作的属性字符串——比如从PDFView读取页面文本——你可以遍历所有的属性,并分析出它们在哪,包含了什么。
比如下面代码创建了一个字符串“the cat sat on the mat”,其中第1,3,5个单词比其他的大一些。
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
2
我们可以全部枚举这个字符串的字体属性,检查是否有加粗或变为红色的片段。通过enumerateAttribute()就可以做到这些,它会找出你请求的所有属性实例,一个个的传递给你,并附有它们的范围。此外还有一个停止选项,如果设为true,则循环停止。
代码如下:
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
3
还有更普遍的enumerateAttributes()方法,可以告诉人一个特定范围的所有属性。
把一张图放入属性字符串
目前为止,你可能觉得属性字符串看上去很简单,那就让我们把一张图片添加入一个属性字符串右边吧。这在app项目中很有用,这样就能更容易的加载图像文件了。
首先,创建一个常规的可变属性字符串
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
4
第二,创建一个NSTextAttachment实例,这个类特别用于给属性字符串附加图像。
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
5
第三,把这个附加图像放到它自己的属性字符串中,这样接下来就可以把它附到之前的字符串上了。
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
6
最后,把NSTextAttachment添加到完整字符串中
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
7
这样就可以了
在属性字符串中放入超链接
网页链接和其他属性字符串的属性一样,你可以在字符串的任意范围添加NSAttributedStringKey.link,并附带一个URL用于点击链接时展示。
let quote = "Haters gonna hate"
let font = UIFont.systemFont(ofSize: 72)
let attributes = [NSAttributedStringKey.font: font]
let attributedQuote = NSAttributedString(string: quote, attributes: attributes)
8
注意:这里只创建了链接,并没有添加格式,链接会默认显示成蓝色加下划线。你可以根据需要设置文本样式的linkTextAttributes属性。
作者: Paul Hudson
链接: https://www.hackingwithswift.com/articles/113/nsattributedstring-by-example
翻译: cocoachina
本文由 投稿者 创作,文章地址:https://blog.isoyu.com/archives/nsattributedstring-yingyonganli.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:8 月 29, 2018 at 09:47 下午