You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4.0富文本属性下标报错:无法用String访问NSAttributedStringKey字典

解决Swift 4中NSAttributedString属性下标访问的错误

这个错误是Swift 4对NSAttributedString的属性系统做了类型安全升级导致的——原来Swift 3里用字符串作为属性键,Swift 4开始统一使用NSAttributedStringKey类型来管理这些键,所以直接用字符串下标访问[NSAttributedStringKey : Any]类型的字典就会报错。

针对你的YYKit富文本点击场景,有两种修复方式:

方式一:直接使用NSAttributedStringKey(rawValue:)转换

把原来的字符串键转换成NSAttributedStringKey实例,修改后的代码如下:

entemessageText.highlightTapAction = { (containerView: UIView, text: NSAttributedString, range: NSRange, rect: CGRect) -> () in 
    let attributes = text.attributes(at: range.location, effectiveRange: nil) 
    // 将字符串键转为NSAttributedStringKey
    if let attrs = attributes[NSAttributedStringKey(rawValue: "YYTextHighlight")] as? YYTextHighlight { 
        if let url = attrs.userInfo?["url"] as? String { // 这里建议用可选绑定代替强制解包,避免崩溃
            if let urlObj = URL(string: url) {
                self.openUrl(urlObj)
            }
        }
    } 
}

方式二:扩展NSAttributedStringKey封装自定义键(更规范)

为了代码更易读和维护,推荐给NSAttributedStringKey加一个扩展,把YYText的自定义键封装成静态属性:

extension NSAttributedStringKey {
    static let yyTextHighlight = NSAttributedStringKey(rawValue: "YYTextHighlight")
}

然后在代码里直接使用这个静态属性:

entemessageText.highlightTapAction = { (containerView: UIView, text: NSAttributedString, range: NSRange, rect: CGRect) -> () in 
    let attributes = text.attributes(at: range.location, effectiveRange: nil) 
    if let attrs = attributes[.yyTextHighlight] as? YYTextHighlight { 
        if let url = attrs.userInfo?["url"] as? String, let urlObj = URL(string: url) {
            self.openUrl(urlObj)
        }
    } 
}

另外补充一个小建议:代码里的attrs.userInfo!和URL(string: url)!都是强制解包,一旦对应的value不存在或者url格式错误,会直接导致崩溃,所以改成可选绑定更安全,我在上面的代码里已经做了调整。

内容的提问来源于stack exchange,提问作者guru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:05