是否可以通过扩展中的 Swift 4 KeyPaths 在 UIView 上设置 属性?

Is it possible to set a property on UIView via Swift 4 KeyPaths in an extension?

我正在尝试通过扩展在 UIView 上创建一个设置方法,该扩展允许我通过新的 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))

感谢您的帮助。

在您的独立示例中,如果您 选项-单击 path,您将看到它的声明是:

let path: ReferenceWritableKeyPath<UIView, UIColor?>

所以它不仅仅是 KeyPath,而是 ReferenceWritableKeyPath。单击 ReferenceWritableKeyPath 显示它是:

A key path that supports reading from and writing to the resulting value with reference semantics.

所以您在 extension 中使用的 KeyPath 类型限制太多,因为它不允许写入。

KeyPath 更改为 ReferenceWritableKeyPath 传递正确的类型使其工作:

extension UIView {
    func set(color: UIColor, forKeyPath path: ReferenceWritableKeyPath<UIView, UIColor?>) {
        self[keyPath: path] = color
    }
}

view.set(color: .white, forKeyPath: \.backgroundColor)  // success!