macOS Swift:如何将NSDocument变量绑定到自定义NSView变量 [英] macOS Swift: How to bind NSDocument variable to custom NSView variable
问题描述
我有一个带有一个变量的简单自定义 NSView
:
I have a simple custom NSView
with one variable:
class MyView: NSView {
var color: NSColor!
}
在我的 NSDocument
中,我具有相同的变量.
In my NSDocument
I have the same variable.
目前我正在使用一个 NSViewController
,当变量改变时,它通过 NSObjectProtocol
从文档接收消息.这意味着我已经通过默认的 NotificationCenter
设置了通知.然后,控制器在我的视图中通过 IBOutlet
设置颜色.
Currently I am using a NSViewController
that receives messages from the document via the NSObjectProtocol
when the variable changes. Which means I've set up notifications over the default NotificationCenter
. Then the controller sets the color in my view over an IBOutlet
.
效果很好,但是留下了很多胶水代码.
That works quite well but leaves me with a lot of glue code.
我当时想我可以使用 NSObjectController
并将其绑定到文档中的颜色.然后将我的颜色从视图绑定到objectController.
I was thinking I could use a NSObjectController
and bind it to the color in my document. And then bind my color from the view to the objectController.
可能是我出了些问题,因为我很难访问甚至在视图中找不到color变量.它不会显示在Interface Builder故事板中.
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.
我想知道如何在我的视图中准备可绑定的变量?!
I wonder how to prepare the variable in my view to be bindable?!
推荐答案
由于KVC和KVO是在Objective-C运行时上构建的,并且由于Cocoa绑定是在KVC和KVO之上构建的,因此您想要使用Cocoa的任何属性与的绑定需要暴露于Objective-C.至少,这意味着在声明中添加 @objc
:
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. At the bare minimum, that means adding @objc
to the declaration:
@objc var color: NSColor!
但是,如果可以在运行时更改 color
属性,则还需要跳过另外一个障碍.您需要确保在调用属性的setter时将触发KVO通知.苹果公司(Apple)的KVO实现将使用Objective-C魔术来自动向设置器添加所需的通知,但是由于不能保证Swift属性访问会通过Objective-C运行时,因此您需要添加 dynamic
使其可靠运行的关键字:
However, if the color
property can be changed at runtime, there's an additional hurdle you need to jump through; you need to make sure that the KVO notifications will fire whenever the property's setter is called. 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:
@objc dynamic var color: NSColor!
如果 color
是一个依赖于其他内容的计算属性,请改为设置一个 keyPathsForValuesAffecting< Key>
静态属性(暴露给Objective-C),让KVO知道的依赖项:
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:
@objc dynamic var foo: NSColor!
@objc private static let keyPathsForValuesAffectingColor: Set<String> = [#keyPath(foo)]
@objc var color: NSColor! { return self.foo }
如果 foo
发生更改,这将导致触发 color
的通知.
This will cause the notifications for color
to be fired if foo
changes.
无论如何,一旦您的媒体资源符合KVC规范,您就应该能够从Interface Builder绑定东西.
Anyway, once your property is KVC-compliant, you should be able to bind things to it from Interface Builder.
这篇关于macOS Swift:如何将NSDocument变量绑定到自定义NSView变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!