简体   繁体   English

macOS Swift:如何将NSDocument变量绑定到自定义NSView变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM