iOS中给富文本添加超链接

在开发中,点击事件一般都是使用UIButton来实现。有时候也会出现请用户阅读并同意多个协议的情况,不同的协议有不同的跳转,这时就需要做成超链接的形式。在iOS中简单实现超链接的方式就是使用UITextView

实现步骤:

首先,要给文本添加超链接属性(NSAttributedString.Key.link),可以响应超链接的文本默认为蓝色,有两种添加方式:

  • 方式1:设置该属性的value值为要跳转的超链接地址
  • 方式2:设置该属性的value值为自定义URL Scheme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let text = "请阅读并同意《用户注册协议》和《用户隐私协议》,如有疑问,请打开百度官方网站或通过GitHub项目来寻找答案。"
let mutableText = NSMutableAttributedString(string: text)

let rangeOfBaidu = text.range(of: "百度官方网站")
let rangeOfGithub = text.range(of: "GitHub项目")
let rangeOfRegister = text.range(of: "《用户注册协议》")
let rangePrivacy = text.range(of: "《用户隐私协议》")

// 添加超链接属性方法1: 超链接属性值为要打开的超链接地址
mutableText.addAttribute(NSAttributedString.Key.link, value: "https://www.baidu.com", range: NSRange(rangeOfBaidu!,in: text))
mutableText.addAttribute(NSAttributedString.Key.link, value: "https://github.com/", range: NSRange(rangeOfGithub!,in:text))

// 添加超链接属性方法2,超链接属性值设置为自定义的URL Scheme
mutableText.addAttribute(NSAttributedString.Key.link, value: "register://", range: NSRange(rangeOfRegister!,in: text))
mutableText.addAttribute(NSAttributedString.Key.link, value: "privacy://", range: NSRange(rangePrivacy!,in:text))

textView.attributedText = mutableText;
textView.isEditable = false//需要设置textView为不可编辑
textView.delegate = self

然后,实现UITextViewDelegate协议的textView(_:shouldInteractWith:in:)方法,响应超链接。

可以通过对比字符串的range来区分不同的超链接;如果设置了Scheme,也可以通过Scheme来区分。需要注意的是,在该代理方法中,return true时会通过外部浏览器 Safari 来打开超链接地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
// 根据range来获取点击位置
let rangeOfBaidu = textView.text.range(of: "百度官方网站")
let rangeOfGithub = textView.text.range(of: "GitHub项目")
let rangeOfRegister = textView.text.range(of: "《用户注册协议》")
let rangePrivacy = textView.text.range(of: "《用户隐私协议》")

// 根据字符串range响应超链接
if characterRange == NSRange(rangeOfBaidu!,in: textView.text) {
print("通过Safari打开百度网站")
return true // 使用Safari打开超链接,前提是:超链接属性的值是url
}else if characterRange == NSRange(rangeOfGithub!,in: textView.text){
print("通过Safari打开GitHub网站")
return true
}

// 根据设置的URL Scheme来响应不同的超链接
if let scheme = URL.scheme {
// 根据Scheme来区分点击位置
if scheme == "register" {
// 添加自定义操作
print("点击了《用户注册协议》")
}else if scheme == "privacy" {
print("点击了《用户隐私协议》")
}
}
return false// 不做外部跳转时return false
}

demo下载地址:RichTextLinkDemo