我正在尝试通过扩展程序在UIView上创建一个set方法,这将允许我通过新的Swift 4 KeyPaths设置颜色。如果我执行以下操作,则会收到错误Cannot assign to immutable expression of type 'UIColor?'
extension UIView {
func set(color: UIColor, forKeyPath path: KeyPath<UIView, UIColor?>) {
self[keyPath: path] = color // Error: Cannot assign to immutable expression of type 'UIColor?'
}
}
view.set(color: .white, forKeyPath: \.backgroundColor)
如果我在扩展名之外使用它,它可以正常工作:
let view = UIView()
let path = \UIView.backgroundColor
view[keyPath: path] = .white // Works fine
使用旧式KeyPath也可以正常工作:
extension UIView {
func set(color: UIColor, forKeyPath path: String) {
self.setValue(color, forKey: path)
}
}
view.set(color: .white, forKeyPath: #keyPath(UIView.backgroundColor))
感谢您的帮助。
答案 0 :(得分:7)
在您的独立示例中,如果您选项 - 点击path
,您会看到其声明是:
let path: ReferenceWritableKeyPath<UIView, UIColor?>
所以它不仅仅是KeyPath
而是ReferenceWritableKeyPath
。点击ReferenceWritableKeyPath
即可显示:
支持读取和写入结果的关键路径 参考语义的值。
因此,您在KeyPath
中使用的extension
类型限制性太强,因为它不允许写入。
将KeyPath
更改为ReferenceWritableKeyPath
传递正确的类型会使其正常工作:
extension UIView {
func set(color: UIColor, forKeyPath path: ReferenceWritableKeyPath<UIView, UIColor?>) {
self[keyPath: path] = color
}
}
view.set(color: .white, forKeyPath: \.backgroundColor) // success!