Swift 如何从 UITextView 获取链接范围
How to get links ranges from UITextView in Swift
我有一个聊天应用程序 UITextView
带有动态文本(来自服务器或由用户输入)。我需要检测所有类型的 link,而 UITextView
在检测 phone 数字、地址、hyperlink 和日历事件方面做得很好。 UITextView
不足之处在于样式,那里存在多个问题:
- 地址 link 未使用
tintColor
或来自 linkTextAttributes
属性 的颜色或使用 appearance()
代理着色。
- 默认情况下所有 link 都带有下划线。
- 一些 link 的颜色正确,但我看不出为什么某些 link 被省略的模式(看起来它可能与自动换行有关)。
- 设置自定义
underlineStyle
属性时,文本会消失。
所以我认为最好的办法是仍然使用 UITextView
来检测 link,然后创建我自己的属性字符串并按照我想要的方式设置所有样式。为此,我需要 link 的范围,但我找不到获取它们的方法。
我试过这个:
open func enumerateAttributes(in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: ([NSAttributedString.Key : Any], NSRange, UnsafeMutablePointer<ObjCBool>) -> Void)
但是从来没有任何 .link
元素,也没有任何下划线属性(如果我查找的话)。所以问题是,有没有办法以某种方式从 UITextView
获取 link 范围?或者也许有一种方法可以可靠地设置我缺少的 link 的样式?
要检测 Phone 号码、地址等,您实际上是在使用 NSDataDetector
。
这就是您在 InterfaceBuilder 中实际设置的内容:
然后:
let types: NSTextCheckingResult.CheckingType = [.address, .link, .phoneNumber, .date]
let detector = try? NSDataDetector(types: types.rawValue)
let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
matches.forEach {
guard let range = Range([=10=].range, in: text) else { return }
let sub = String(text[range])
print(sub)
}
我有一个聊天应用程序 UITextView
带有动态文本(来自服务器或由用户输入)。我需要检测所有类型的 link,而 UITextView
在检测 phone 数字、地址、hyperlink 和日历事件方面做得很好。 UITextView
不足之处在于样式,那里存在多个问题:
- 地址 link 未使用
tintColor
或来自linkTextAttributes
属性 的颜色或使用appearance()
代理着色。 - 默认情况下所有 link 都带有下划线。
- 一些 link 的颜色正确,但我看不出为什么某些 link 被省略的模式(看起来它可能与自动换行有关)。
- 设置自定义
underlineStyle
属性时,文本会消失。
所以我认为最好的办法是仍然使用 UITextView
来检测 link,然后创建我自己的属性字符串并按照我想要的方式设置所有样式。为此,我需要 link 的范围,但我找不到获取它们的方法。
我试过这个:
open func enumerateAttributes(in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: ([NSAttributedString.Key : Any], NSRange, UnsafeMutablePointer<ObjCBool>) -> Void)
但是从来没有任何 .link
元素,也没有任何下划线属性(如果我查找的话)。所以问题是,有没有办法以某种方式从 UITextView
获取 link 范围?或者也许有一种方法可以可靠地设置我缺少的 link 的样式?
要检测 Phone 号码、地址等,您实际上是在使用 NSDataDetector
。
这就是您在 InterfaceBuilder 中实际设置的内容:
然后:
let types: NSTextCheckingResult.CheckingType = [.address, .link, .phoneNumber, .date]
let detector = try? NSDataDetector(types: types.rawValue)
let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
matches.forEach {
guard let range = Range([=10=].range, in: text) else { return }
let sub = String(text[range])
print(sub)
}