Swift 4 Ошибка преобразования - NSAttributedStringKey: Любой
Недавно я конвертировал свое приложение, и я продолжаю получать сообщение об ошибке
"Невозможно преобразовать значение типа '[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
}
Ответы
Ответ 1
Почему вы получили эту ошибку
Ранее ваши attributes
определялись как [String: Any]
, где ключ берется из NSAttributedStringKey
в виде строки или NSAttributedString.Key
в Swift 4.2.
Во время миграции компилятор пытается сохранить тип [String: Any]
. Однако NSAttributedStringKey
становится структурой в swift 4. Таким образом, компилятор пытается изменить это на строку, получая ее необработанное значение.
В этом случае setTitleTextAttributes
ищет [NSAttributedStringKey: Any]
но вы [NSAttributedStringKey: Any]
[String: Any]
Чтобы исправить эту ошибку:
Удалите .rawValue
и .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]
И в Swift 4.2,
let attributes = [NSAttributedString.Key.font:
UIFont(name: "Helvetica-Bold", size: 15.0)!,
NSAttributedString.Key.foregroundColor: UIColor.white] as! [NSAttributedStringKey: Any]
Ответ 2
Ожидается NSAttributedStringKey
(NSAttributedStringKey.font
) и вы отправляете String
(NSAttributedStringKey.font.rawValue
).
Итак, замените NSAttributedStringKey.font.rawValue
на NSAttributedStringKey.font
, как показано ниже:
let attributes = [NSAttributedStringKey.font: UIFont(name: "Helvetica-Bold", size: 15.0)!, NSAttributedStringKey.foregroundColor: UIColor.white]
Ответ 3
Как отмечалось в предыдущих ответах, NSAttributedStringKey
был изменен на структуру в Swift 4. Однако другие объекты, которые используют NSAttributedStringKey
, по-видимому, не обновлялись одновременно.
Самое простое исправление без изменения какого-либо другого кода - это добавить .rawValue
ко всем входящим в набор NSAttributedStringKey
сеттерам - превратить имена ключей в String
s:
let attributes = [
NSAttributedStringKey.font.rawValue: UIFont(name: "Helvetica-Bold", size: 15.0)!,
NSAttributedStringKey.foregroundColor.rawValue: UIColor.white
] as [String : Any]
Обратите внимание, что теперь вам не понадобится !
в as
.
В качестве альтернативы вы можете пропустить приведение as
в конце, объявив массив [String : Any]
upfront:
let attributes: [String : Any] = [
NSAttributedStringKey.font.rawValue: UIFont(name: "Helvetica-Bold", size: 15.0)!,
NSAttributedStringKey.foregroundColor.rawValue: UIColor.white
]
Конечно, вам нужно добавить .rawValue
для каждого элемента NSAttributedStringKey
, который вы установили.
Ответ 4
Линейный ответ верен для случаев, когда вам все еще нужно использовать [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
}