如何解决对属性使用 getter/setter 使其不会出现在反射镜像中
我一直在尝试为我的自定义组件实现主题逻辑。我将使用 ZFButton 作为示例。
当应用程序启动时,我会实例化 ZFbutton 并设置我希望这个主题具有的任何特征:
let theme = ZFButton()
theme.backgroundColor = .red //UIButton property
theme.cornerRadius = 8 //ZFButton property
theme.borderColor = .green //ZFButton property
theme.borderWidth = 1 //ZFButton property
ZFButton.themes.append(theme)
它驻留在 ZFButton 中,如下所示:
public static var themes = [ZFButton]()
在我的 ZFButton 中,我有以下属性,它允许我从 IB 属性检查器中选择我想用于该特定 ZFButton 的主题
@IBInspectable public var theme: Int = 0 { didSet { self.setupTheme() } }
最后,一旦设置了主题属性,就会调用 setupTheme(),在此过程中,我尝试将给定主题的所有属性中的值集复制到 ZFButton 的这个特定实例。为此,我使用反射:
private func setupTheme() {
if ZFButton.themes.count > self.theme {
let theme = ZFButton.themes[self.theme]
let mirror = Mirror(reflecting: theme)
for child in mirror.children {
if let label = child.label,label != "theme",//check to prevent recursive calls
self.responds(to: Selector(label)) {
self.setValue(child.value,forKey: label)
print("Property name:",child.label)
print("Property value:",child.value)
}
}
}
}
现在我有两个问题:
1 - 具有 setter/getter 的属性不会出现在反射中,例如:
@IBInspectable public var borderColor: UIColor {
set { layer.borderColor = newValue.cgColor }
get { return UIColor(cgColor: layer.borderColor!) }
}
而使用 didSet 的属性可以,例如:
@IBInspectable public var iconText: String = "" { didSet { self.setupIcon() } }
但是,我确实需要一个 getter 来返回 borderColor
中的 layer
。
2 - 当使用 Mirror 来反映所有 ZFButton 属性时,除了 (1) 中描述的问题之外,我也没有获得 UIButton 属性,有没有办法获得 ZFButton 的超类 (UIButton) 属性?
解决方法
对于第一个问题,我最终使用了以下扩展,它确实看到了与 Mirror 不同的 getter/setter 属性:
hy 1.0a1+114.g2abb33b1 using CPython(default) 3.8.6 on Linux
=> (defmacro test [x] (str x))
<function test at 0x7fe0476144c0>
=> (test abc)
"abc"
至于第二个问题,我最终将每个属性从主题复制到按钮,因为它们始终相同。目标是避免每次在 ZFButton 中实现新内容时都必须维护 Theme 类来桥接值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。