这个
NSAttributedString.Key.foregroundColor: view.tintColor
触发这个警告
Expression implicitly coerced from 'UIColor?' to 'Any'
但是那个警告不应该是
Expression implicitly coerced from 'UIColor?' to 'UIColor'
因为这个属性
NSAttributedString.Key.foregroundColor
是 UIColor
类型吗?
Note: This only started happening after updating to Swift 5, Xcode 10.2.
这里有更多的上下文:
override func viewDidLoad() {
super.viewDidLoad()
UIBarButtonItem.appearance().setTitleTextAttributes(
[
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 40),
NSAttributedString.Key.foregroundColor: view.tintColor
], for: .normal)
}
最佳答案
这与.foregroundColor
无关。它与 .tintColor
和 setTitleTextAttributes
有关。
此参数的类型为[NSAttributedString.Key : Any]
。它没有以任何方式考虑每个 key 的文档。它不知道也不关心这应该是一个 UIColor
。如果你传递了“squid”,这将在没有警告的情况下编译(它不会工作,但它会编译):
UIBarButtonItem.appearance().setTitleTextAttributes(
[
.font: UIFont.systemFont(ofSize: 40),
.foregroundColor: "squid",
], for: .normal)
它所关注的只是您将 view.tintColor
分配给 Any
类型的值。
问题是 view.tintColor
不是 UIColor
,而是 UIColor!
。 .tintColor
实际上不可能为 nil,但可以将它设置为 nil:
view.tintColor // r 0.0 g 0.478 b 1.0 a 1.0
view.tintColor = .red
view.tintColor // r 1.0 g 0.0 b 0.0 a 1.0
view.tintColor = nil
view.tintColor // r 0.0 g 0.478 b 1.0 a 1.0
这在 ObjC 中有意义,但在 Swift 中表达它的唯一方法是使用 !
类型。当您将 !
类型分配给其他事物时,它们将变为 ?
类型。这意味着您在接受 Any
(字典的值)的地方使用 UIColor?
。
将可选项用作 Any
可能很危险,因为它会产生很多奇怪的极端情况。例如,您不能通过 Any 往返可选;它被压缩成它的基本类型:
let x: Any = Optional(1)
x as? Int? // Cannot downcast from 'Any' to a more optional type 'Int?'
x as? Int // 1
在使用 Any 时,会遇到很多这样的小问题。
当然,您不想与 Any 一起工作。这不是你的错。但这就是 Swift 提示的原因。
有多种解决方案,具体取决于您的喜好。你可以使用 !
:
.foregroundColor: view.tintColor!
您可以添加 as Any
来消除警告:
.foregroundColor: view.tintColor as Any
我个人会使用 as Any
。
或者您可以详细说明并提前卸载值(我不建议这样做):
let tintColor = view.tintColor ?? .blue
UIBarButtonItem.appearance().setTitleTextAttributes(
[
.font: UIFont.systemFont(ofSize: 40),
.foregroundColor: tintColor,
], for: .normal)
关于swift - '强制为任何',但属性是 UIColor 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55349097/