web-dev-qa-db-fra.com

Swift 4 Erreur de conversion - NSAttributedStringKey: Any

J'ai récemment converti mon application et je continue à avoir l'erreur

"Impossible de convertir la valeur du type '[String: Any]' en un type d'argument attendu '[NSAttributedStringKey: Any]?'

barButtonItem.setTitleTextAttributes(attributes, for: .normal)

Code entier:

 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
}
29
Eazy

Pourquoi tu as cette erreur

Auparavant, votre attributes est défini comme [String: Any], où la clé provient de NSAttributedStringKey sous forme de chaîne ou NSAttributedString.Key in Swift 4.2

Pendant la migration, le compilateur essaie de conserver le [String: Any] type. Cependant, NSAttributedStringKey devient une structure Swift 4.). Le compilateur essaie donc de changer cela en chaîne en obtenant sa valeur brute.

Dans ce cas, setTitleTextAttributes recherche [NSAttributedStringKey: Any] mais vous avez fourni [String: Any]

Pour corriger cette erreur:

Retirer .rawValue et transformez votre attributes comme [NSAttributedStringKey: Any]

À savoir, changez cette ligne suivante

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]

Et dans Swift 4.2,

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

Son attente NSAttributedStringKey (NSAttributedStringKey.font) et vous envoyez String (NSAttributedStringKey.font.rawValue).

Veuillez donc remplacer NSAttributedStringKey.font.rawValue avec NSAttributedStringKey.font comme ci-dessous:

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

Comme indiqué dans les réponses précédentes, NSAttributedStringKey a été remplacé par une structure dans Swift 4.). Cependant, d'autres objets qui utilisent NSAttributedStringKey apparemment, il n'a pas été mis à jour en même temps.

La solution la plus simple, sans avoir à changer aucun autre code, est de ajouter.rawValue to all vos occurrences de NSAttributedStringKey setters - transformer les noms de clé en Strings:

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

Notez que vous n'aurez pas besoin du ! au as maintenant, non plus.

Alternativement, vous pouvez ignorer le cast as à la fin en déclarant que le tableau est [String : Any] à l'avant:

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

Bien sûr, vous devez encore ajouter le .rawValue pour chaque élément NSAttributedStringKey que vous avez défini.

5
leanne

La réponse de Leanne est correcte pour les cas où vous devez toujours utiliser [String : Any] et non [NSAttributedStringKey : Any].

Par exemple, dans UIKit UITextView.typingAttributes Est toujours de type [String : Any]. Donc, pour cette propriété, vous devez utiliser les attributs convertis (y compris les attributs personnalisés):

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() est une fonction définie par extension dans l'un des fichiers de votre projet:

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

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

        return convertedDictionary
}
2
roxanneM