Swift 4 - Xcode 9 beta 4 - NSKernAttributeName vs NSAttribut



iOS部署目标:iOS 9.3, 基本SDK:最新的iOS(iOS 11.0(, Xcode 9 Beta 4, 斯威夫特 4

以下代码在 Swift 3、Xcode 8 中构建和运行:

let kern = (CTRunGetAttributes(run) as? [String : Any])?
[NSKernAttributeName] as? CGFloat ?? 0

但是,Swift 4 迁移器将其转换为:

let kern = (CTRunGetAttributes(run) as? [String : Any])?
[NSAttributedStringKey.kern] as? CGFloat ?? 0

Xcode 9 现在抱怨:

Cannot subscript a value of type '[String : Any]' with an index of type 'NSAttributedStringKey'

根据检查员的说法,"NSAttributedStringKey"仅在iOS 11中可用。(请记住,我的目标是iOS 9(。

如果我将"NSAttributedStringKey.kern"替换为"NSKernAttributeName",则错误仍然存在。

命令单击"NSKernAttributeName"告诉我它的可用性是iOS 6。但是,检查器还声称其类型是"NSAttributedStringKey",仅在iOS 11中可用。我不知道这仅仅是 API 演示的人工制品,还是填充物,还是我缺少的东西。

问:如何使用向后兼容 iOS 9 的NSKernAttributeName(或其现代化版本(和 Swift 4?

感谢您的任何帮助。

将字典键入为 [NSAttributedStringKey : Any] 而不是 [String : Any]。Swift 覆盖层中的所有糖,因此即使在较旧的 macOS/OS X 版本上也应该可以工作。

编辑:我应该澄清一下我的最后一句话。NSAttributedStringKey 以及 Swift 4 中的所有其他新"Key"类型只存在于 Swift 中,而不是 Objective-C 中。当带有NSAttributedStringKey键的字典桥接到Objective-C时,所有键都将转换为NSStrings。由于你正在使用的实际 Foundation、UIKit 等框架是用 C/Objective-C 编写的,这将"正常工作",你不必担心声称 NSAttributedStringKey 仅限 10.11 的文档。

textField.defaultTextAttributes[NSAttributedStringKey.kern.rawValue] = 16

Swift 4

如果您不想忽略警告并无论如何投射,则可以将它们干净地复制到新字典中。

var attributes: [NSAttributedStringKey: Any] = [:]
textField.defaultTextAttributes.forEach{
attributes[NSAttributedStringKey(rawValue: $0.key)] = $0.value
}

最新更新