Swift 4转换错误 - NSAttributedStringKey:Any

时间:2017-09-20 06:22:20

标签: swift4

我最近转换了我的应用,并且一直收到错误

  

"无法转换类型的值' [String:Any]'预期的参数类型' [NSAttributedStringKey:Any]?'

barButtonItem.setTitleTextAttributes(attributes, for: .normal)

整个代码:

 class func getBarButtonItem(title:String) -> UIBarButtonItem {
    let barButtonItem = UIBarButtonItem.init(title: title, style: .plain, target: nil, action: nil)
    let attributes = [NSAttributedStringKey.font.rawValue:  UIFont(name: "Helvetica-Bold", size: 15.0)!, NSAttributedStringKey.foregroundColor: UIColor.white] as! [String : Any]
    barButtonItem.setTitleTextAttributes(attributes, for: .normal)

    return barButtonItem
}

4 个答案:

答案 0 :(得分:44)

为什么会出现此错误

以前,您的attributes定义为[String: Any],其中密钥来自NSAttributedStringKey字符串。

在迁移期间,编译器会尝试保留[String: Any]类型。但是,NSAttributedStringKey成为swift 4中的结构。因此编译器尝试通过获取其原始值将其更改为字符串。

在这种情况下,setTitleTextAttributes正在寻找[NSAttributedStringKey: Any],但您提供了[String: Any]

要修复此错误:

移除.rawValue并将attributes投射为[NSAttributedStringKey: Any]

即,更改以下行

let attributes = [NSAttributedStringKey.font.rawValue:
    UIFont(name: "Helvetica-Bold", size: 15.0)!, 
    NSAttributedStringKey.foregroundColor: UIColor.white] as! [String : Any]

let attributes = [NSAttributedStringKey.font:
    UIFont(name: "Helvetica-Bold", size: 15.0)!, 
    NSAttributedStringKey.foregroundColor: UIColor.white] as! [NSAttributedStringKey: Any]

答案 1 :(得分:15)

它期待NSAttributedStringKeyNSAttributedStringKey.font),您发送StringNSAttributedStringKey.font.rawValue)。

所以请将NSAttributedStringKey.font.rawValue替换为NSAttributedStringKey.font,如下所示:

let attributes = [NSAttributedStringKey.font:  UIFont(name: "Helvetica-Bold", size: 15.0)!, NSAttributedStringKey.foregroundColor: UIColor.white]

答案 2 :(得分:5)

如前面的答案中所述,NSAttributedStringKey已更改为Swift 4中的结构。但是,使用 .rawValue的其他对象显然未在同一时间更新时间。

最简单的解决方法,无需更改任何其他代码,追加 NSAttributedStringKey 所有出现String个设置者 - 将密钥名称转换为let attributes = [ NSAttributedStringKey.font.rawValue: UIFont(name: "Helvetica-Bold", size: 15.0)!, NSAttributedStringKey.foregroundColor.rawValue: UIColor.white ] as [String : Any] s:

!

请注意,您现在也不需要as的{​​{1}}。

或者,您可以通过在前面声明数组为as来跳过最后的[String : Any]强制转换:

let attributes: [String : Any] = [
    NSAttributedStringKey.font.rawValue:  UIFont(name: "Helvetica-Bold", size: 15.0)!,
    NSAttributedStringKey.foregroundColor.rawValue: UIColor.white
]

当然,您仍然需要为您设置的每个.rawValue项附加NSAttributedStringKey

答案 3 :(得分:2)

leanne's answer对于您仍然需要使用[String : Any]而非[NSAttributedStringKey : Any]的情况是正确的。

例如,在UIKit UITextView.typingAttributes中仍然是[String : Any]类型。因此,对于该属性,您必须使用转换后的属性(包括自定义属性):

let customAttributeName = "MyCustomAttributeName"
let customValue: CGFloat = 15.0

let normalTextAttributes: [NSAttributedStringKey : Any] =
            [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 14.0),
             NSAttributedStringKey.foregroundColor : UIColor.blue,
             NSAttributedStringKey.backgroundColor : UIColor.clear,
             NSAttributedStringKey(rawValue: customAttributeName): customValue]

textView.typingAttributes = normalTextAttributes.toTypingAttributes()

其中toTypingAttributes()是由任何项目文件中的扩展名定义的函数:

extension Dictionary where Key == NSAttributedStringKey {
    func toTypingAttributes() -> [String: Any] {
        var convertedDictionary = [String: Any]()

        for (key, value) in self {
            convertedDictionary[key.rawValue] = value
        }

        return convertedDictionary
}