ios - 在 UITextView 中点击 URL 时 iOS 应用程序崩溃
问题描述
我正在尝试在文本中设置具有多个链接的 UITextView。我的实现基于此处描述的建议。大多数链接按预期工作,但是点击其中一些会使应用程序崩溃并出现以下错误EXC_BREAKPOINT (code=1, subcode=0x185646694)
:
崩溃错误
调用堆栈
我的 UITextView 配置代码:
private var actionableLinks = [(String, ()->Void)]() // each link = (actionableString, tapAction)
private func setupMessageText() {
guard messageTextView != nil else { return }
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.paragraphSpacingBefore = 16
let attributedText = NSMutableAttributedString(string: messageText, attributes: [
.font: messageTextView.font!,
.foregroundColor: messageTextView.textColor!,
.paragraphStyle: paragraphStyle
])
addActionableLinks(to: attributedText)
messageTextView?.attributedText = attributedText
}
private func addActionableLinks(to attributedText: NSMutableAttributedString) {
actionableLinks.forEach {
let actionableString = $0.0
if let nsRange = messageText.nsRange(of: actionableString) {
attributedText.addAttribute(.link, value: actionableString, range: nsRange)
}
}
}
为了处理点击动作,我使用了正确的 UITextViewDelegate 方法:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
let tappedLinkString = URL.absoluteString
if let link = actionableLinks.first(where: { $0.0 == tappedLinkString }) {
let tapAction = link.1
tapAction()
return false
}
return true
}
此屏幕的故事板配置(我在故事板中设置了 UITextView 委托):
故事板配置
任何见解将不胜感激!谢谢。
解决方案
问题解决了!感谢Larme提供的快速见解和资源。
这确实是一个尝试在内部转换为 URL 的 UITextView 中使用错误字符串作为链接的情况。由于这是一个包含空格的字符串,因此 Apple 对 URL 的内部转换失败。
我的字符串“支持”链接正确并且有效,但是另一个字符串“新条款和条件”失败了。
解决方案
为了解决这个问题,我在将链接属性添加到 UITextView 的属性文本时使用了百分比编码。
private func addActionableLinks(to attributedText: NSMutableAttributedString) {
actionableLinks.forEach {
let actionableString = $0.0
if let nsRange = messageText.nsRange(of: actionableString) {
let escapedActionableString = escapedString(actionableString)
attributedText.addAttribute(.link, value: escapedActionableString, range: nsRange)
}
}
}
private func escapedString(_ string: String) -> String {
return string.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? string
}
我还更改了委托方法以检查是否与转义字符串匹配:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
let tappedLinkString = URL.absoluteString
for (actionableString, tapAction) in actionableLinks {
let escapedActionableString = escapedString(actionableString)
if escapedActionableString == tappedLinkString {
tapAction()
return false
}
}
return true
}
谢谢!
推荐阅读
- android - 颤动:将所有小部件排列成行
- mule-studio - 无法在 mule 独立服务器中部署 mule 应用程序
- angular - 检查预期 URL 并显示实际 URL
- xml - XSLT 1.0 如何在条件为真时产生空结果和/或中止转换
- java - 为什么 int 数据类型在 JAVA 中的行为是这样的?
- java - 我不明白这一系列代码的编译顺序
- google-chrome-extension - Chrome 扩展消息侦听器不起作用
- c# - c# - WPF 在没有按钮的对话框中关闭对话框
- typescript - Ag-grid cellValueChanged 样式更新
- android - 对于 OPPO 手机等少数设备,setAlarmClock() 无法在 dozo 模式下工作