我正在学习KVC和绑定。目前,我正在尝试将NSTextField绑定到计算属性colorWallStr
。我已将滑块的值绑定到相应的颜色变量,并将标签的值绑定到计算属性。
但是,当我移动幻灯片时,标签的内容不会改变。
// Inside MainWindowController
dynamic var colorRed: CGFloat = 1.0
dynamic var colorGreen: CGFloat = 1.0
dynamic var colorBlue: CGFloat = 0.0
dynamic var colorWallStr: String {
get {
return "R: \(colorRed) G: \(colorGreen) B: \(colorBlue)"
}
}
将标签直接粘贴到颜色变量时工作正常。
谢谢@ vadian的回答。现在我可以使用属性didSet
更新标签以触发更新标签方法(见下文)。
dynamic var colorBlue: CGFloat = 0.0 {
didSet {
updateLabel()
}
}
func updateLabel() {
colorWall = "R: \(colorRed) G: \(colorGreen) B: \(colorBlue)"
}
如果字符串插值中使用的属性不更新封闭的计算属性,那么为什么以下代码片段不起作用?
dynamic var colorWall: String {
get {
let red = colorRed
let green = colorGreen
let blue = colorBlue
return "R: \(red) G: \(green) B: \(blue)"
}
}
答案 0 :(得分:5)
Key-Value Observering API允许您通过注册依赖键来处理这种情况。以下是文档介绍主题的方法:
在许多情况下,一个属性的值取决于另一个对象中的一个或多个其他属性的值。如果一个属性的值发生更改,则还应标记派生属性的值以进行更改。
在这种情况下,colorWallString
的值取决于三个颜色变量的值,因此您需要做的就是实现一个明确的类方法:
// It's crucial that you get the signature of this method correct,
// otherwise it'll just be ignored.
class func keyPathsForValuesAffectingColorWallStr() -> Set<NSObject> {
return Set<NSObject>(arrayLiteral: "colorRed", "colorBlue", "colorGreen")
}
如代码段中所述,用于标记依赖键的方法格式至关重要;你可以(而且应该)阅读relevant documentation here。
答案 1 :(得分:1)
字符串插值中使用的属性不会更新封闭的计算属性。
你可以这样做
dynamic var colorRed: CGFloat = 1.0 { didSet { updateLabel() } }
dynamic var colorGreen: CGFloat = 1.0 { didSet { updateLabel() } }
dynamic var colorBlue: CGFloat = 0.0 { didSet { updateLabel() } }
dynamic var colorWallStr = ""
func updateLabel()
{
colorWallStr = String(format:"R: %.2f G: %.2f B: %.2f ", colorRed, colorGreen, colorBlue)
}
答案 2 :(得分:1)
对于Xcode 9.0,Swift 4:
class SampleViewController: NSViewController {
@objc dynamic var colorRed: CGFloat = 1.0
@objc dynamic var colorGreen: CGFloat = 1.0
@objc dynamic var colorBlue: CGFloat = 0.0
@objc dynamic var colorWallStr: String {
get {
return "R: \(colorRed) G: \(colorGreen) B: \(colorBlue)"
}
}
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
switch key {
case "colorWallStr" :
return Set(["colorRed", "colorGreen", "colorBlue"])
default :
return super.keyPathsForValuesAffectingValue(forKey: key)
}
}
}
小提示:
NSViewController
代替NSWindowController
。更多信息:
答案 3 :(得分:0)
“在某些情况下,价值可能取决于另一个。例如,如果你有一个Person类,其计算属性fullName依赖于属性firstName和lastName,那么当firstName或lastName更改时,是否可以通知fullName的观察者,这不是很好吗? KVO的设计师也这么认为,这也是他们实现定义依赖键的约定的原因。
要定义键的依赖项,必须实现一个特殊命名的类方法,该方法返回一组键路径。在上面的示例中,您将实现keyPathsForValuesAffectingFullName():
“
摘录自:亚伦的希勒加斯。 “OS X的可可编程:大书呆子牧场指南,5 / e(大书呆子牧场指南)。”iBooks。