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

Posted

技术标签:

【中文标题】是否可以通过扩展中的 Swift 4 KeyPaths 在 UIView 上设置属性?【英文标题】:Is it possible to set a property on UIView via Swift 4 KeyPaths in an extension? 【发布时间】:2017-07-08 10:03:31 【问题描述】:

我正在尝试通过一个扩展在 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))

感谢您的帮助。

【问题讨论】:

【参考方案1】:

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

let path: ReferenceWritableKeyPath<UIView, UIColor?>

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

支持读取和写入结果的关键路径 具有引用语义的值。

因此,您在 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!

【讨论】:

以上是关于是否可以通过扩展中的 Swift 4 KeyPaths 在 UIView 上设置属性?的主要内容,如果未能解决你的问题,请参考以下文章

Swift中的#pragma mark?

Swift:扩展print()函数的功能

使用swift 4访问扩展和另一个类中的fileprivate和private变量

扩展中的延迟加载属性(Swift)

替换数组中的多次出现 - Swift 4.1

如何检查String是否是Swift中的Int?