[英]macOS Swift: How to bind NSDocument variable to custom NSView variable
I have a simple custom NSView
with one variable: 我有一个带有一个变量的简单自定义
NSView
:
class MyView: NSView {
var color: NSColor!
}
In my NSDocument
I have the same variable. 在我的
NSDocument
我有相同的变量。
Currently I am using a NSViewController
that receives messages from the document via the NSObjectProtocol
when the variable changes. 当前,我正在使用
NSViewController
,当变量更改时,该NSViewController
通过NSObjectProtocol
从文档接收消息。 Which means I've set up notifications over the default NotificationCenter
. 这意味着我已经通过默认的
NotificationCenter
设置了通知。 Then the controller sets the color in my view over an IBOutlet
. 然后,控制器在我的视图中通过
IBOutlet
设置颜色。
That works quite well but leaves me with a lot of glue code. 效果很好,但是给我留下了很多胶合代码。
I was thinking I could use a NSObjectController
and bind it to the color in my document. 我当时想我可以使用
NSObjectController
并将其绑定到文档中的颜色。 And then bind my color from the view to the objectController. 然后将我的颜色从视图绑定到objectController。
Probably I got something wrong because I am having a hard time to access or even find the color variable in the view. 可能是我出了些问题,因为我很难访问甚至无法在视图中找到颜色变量。 It doesn't show up in the Interface Builder Storyboard.
它不会显示在Interface Builder故事板上。
I wonder how to prepare the variable in my view to be bindable?! 我想知道如何准备我认为该变量可绑定?
Since KVC and KVO are built on the Objective-C runtime, and since Cocoa Bindings is built on top of KVC and KVO, any properties you want to use Cocoa Bindings with need to be exposed to Objective-C. 由于KVC和KVO是在Objective-C运行时上构建的,并且由于Cocoa绑定是在KVC和KVO之上构建的,因此要使用Cocoa绑定的任何属性都必须公开给Objective-C。 At the bare minimum, that means adding
@objc
to the declaration: 至少,这意味着在声明中添加
@objc
:
@objc var color: NSColor!
However, if the color
property can be changed at runtime, there's an additional hurdle you need to jump through; 但是,如果可以在运行时更改
color
属性,则还需要克服其他障碍。 you need to make sure that the KVO notifications will fire whenever the property's setter is called. 您需要确保在调用属性的setter时将触发KVO通知。 Apple's implementation of KVO will use Objective-C magic to automatically add the needed notifications to the setter, but since Swift property accesses aren't guaranteed to go through the Objective-C runtime, you need to add the
dynamic
keyword for this to work reliably: 苹果公司(Apple)的KVO实现将使用Objective-C魔术来自动向设置器添加所需的通知,但是由于不能保证Swift属性访问会通过Objective-C运行时,因此您需要添加
dynamic
关键字才能可靠地工作:
@objc dynamic var color: NSColor!
If color
is a computed property that depends on something else, set up a keyPathsForValuesAffecting<Key>
static property instead (exposed to Objective-C) to let KVO know of the dependency: 如果
color
是一个依赖于其他内容的计算属性,请keyPathsForValuesAffecting<Key>
设置一个keyPathsForValuesAffecting<Key>
静态属性(暴露给Objective-C),让KVO知道该依赖关系:
@objc dynamic var foo: NSColor!
@objc private static let keyPathsForValuesAffectingColor: Set<String> = [#keyPath(foo)]
@objc var color: NSColor! { return self.foo }
This will cause the notifications for color
to be fired if foo
changes. 如果
foo
更改,这将触发color
通知。
Anyway, once your property is KVC-compliant, you should be able to bind things to it from Interface Builder. 无论如何,一旦您的属性符合KVC,您就应该能够从Interface Builder绑定东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.