我正在尝试使用以下方法在属性字符串中创建链接:
matches = regex.matches(in: strings, options: [], range: NSRange(strings.startIndex..., in: strings))
for match in matches {
rangeBetweenQuotes = match.range(at: 1)
let swiftRange = Range(rangeBetweenQuotes, in: strings)!
let link:String = String(strings[swiftRange])
attributedString.addAttribute(.link, value: link, range: rangeBetweenQuotes)
}
我知道如果我只是添加一个字体属性而不是链接,上述工作就会起作用。 所以我的正则表达式有效。但是,在添加链接属性时,我遇到了问题。 当我按照上面编写的代码编译并运行应用程序时,我点击链接并收到错误:线程 1:EXC_BAD_INSTRUCTION(代码 = EXC_I386_INVOP,子代码 = 0x0。它显示在应用委托类中。
据我所知,最后两行代码抛出了错误。
let link:String = String(strings[swiftRange])
attributedString.addAttribute(.link, value: link, range: rangeBetweenQuotes)
为了进行调试,我在上面的最后两行代码之间放置了一个断点。我可以看到变量link
包含正确的字符串。该字符串也可以在addAttribute
的value
参数中找到。
点击链接时,会在运行时引发错误。 我知道是这种情况,因为我可以用字符串文字替换或分配link
,即"test"
,链接工作正常,我可以使用
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
将"test"字符串文本分配给插座。
使用调试器,我遇到了以下内容,我在value
参数的link
变量内的向下钻取菜单中发现了以下内容addAttribute.
(桥接对象) _object = 从值中提取数据失败
这表明变量有问题。不?
我尝试使用URL(string:"")
将String
类型的link
变量转换为URL
,这也不起作用。
我相信答案涉及以下函数中的 URL 类型是否与传入其中的任何类型兼容。
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool
下面的代码可以在不抛出错误的情况下工作。 看看URL(fileURLWithPath: )
... let swiftRange = Range(rangeBetweenQuotes, in: strings)!
let link:String = String(strings[swiftRange])
let link2 = URL(fileURLWithPath: link)
attributedString.addAttribute(.link, value: link2, range: rangeBetweenQuotes)
我不断遇到的崩溃不是源于执行函数addAttribute参数值时的错误,该函数采用任何对象类型。在调试错误时,我发现addAttribute中的参数值包含我传入的字符串值。如上所述,问题起源于以下函数:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool
它需要一个网址。当我尝试
使用URL(string:"")
转换不起作用。我一直得到一个空值,点击链接时当然会抛出错误。但是,我可以安全地将变量传递到参数中应该与 URL:URL 交互时字符串类型变量 使用以下方法转换为网址:
URL(fileURLWithPath: link)
我仍然不明白为什么应该与URL:URL交互接受字符串文字,而String(string[swiftRange]),上文,不起作用。有什么想法吗?
编辑。。。进一步解释
我知道为什么URL类型接受一个字符串文字而不是另一个字符串文字的答案。 有效的URL类型不能在字符串中包含空格。URL(fileURLWithPath:)之所以有效,是因为它用 %20 填充空格。
我希望这对未来的某人有所帮助。
一个原因可能是NSRange
转换为Range<String.Index>
,反之亦然。强烈建议您不要使用string.count
和NSString
绕道。
有方便的 API 可以安全地转换类型
matches = regex.matches(in: string, range: NSRange(string.startIndex..., in: string))
和
let swiftRange = Range(rangeBetweenQuotes, in: string)!
let link = String(string[swiftRange])