如何使用 Xcode 4 绑定到 Cocoa 中的自定义视图?

发布于 2024-12-14 20:47:02 字数 1016 浏览 1 评论 0原文

在编写 Mac 应用程序和使用 Cocoa 方面,我是一个初学者,所以请原谅我的无知。

我正在创建一个自定义视图,它公开一些属性,然后我可以将其绑定到 NSObjectController。由于它是自定义视图,因此绑定检查器显然不会列出我添加到视图中的任何属性,然后我可以使用 Interface Builder 绑定到这些属性。

在向 Stackoverflow/Google 寻求帮助后,我偶然发现了几种可能的解决方案,但似乎都不适合我的情况。第一个建议创建一个 IBPlugin,这意味着我的绑定将在绑定检查器中可用。然后我可以使用 IB 将视图绑定到控制器。显然 Xcode 4 不支持 IBPlugins,所以这是不可能的。我还假设(也许是错误的)IBPlugins 不再受支持,因为现在有更好的方法来做这样的事情?

第二个选项是以编程方式将控制器绑定到视图。我对如何实现这一目标有点困惑。是否需要子类化 NSObjectController 以便我可以添加调用以绑定到视图?我需要在视图中添加任何内容来支持这一点吗?我见过的一些例子说你需要重写绑定方法,而另一些例子则说你不需要。

另外,我注意到一些示例自定义视图在初始化程序中调用 [self ExposureBinding:@"bindingName"] 。从我从各种来源收集到的信息来看,这是与 IBPlugins 相关的事情,如果我不使用它们,我就不需要做这些事情。这是正确的吗?

我在 Stackoverflow 此处 这似乎讨论了与我的问题非常相似的问题,但对于最佳答案没有任何明确的获胜者。 noa 在 9 月 12 日发表的最后一条评论似乎很有趣,尽管他们提到您应该调用 exposeBinding:。这个评论是否走在正确的轨道上?调用exposeBinding 真的有必要吗?

对任何愚蠢的问题表示歉意。非常感谢任何帮助。

I'm a beginner when it comes to writing Mac apps and working with Cocoa, so please forgive my ignorance.

I'm looking to create a custom view, that exposes some properties, which I can then bind to an NSObjectController. Since it's a custom view, the Bindings Inspector obviously doesn't list any of the properties I've added to the view that I can then bind to using Interface Builder.

After turning to the Stackoverflow/Google for help, I've stumbled across a couple of possible solutions, but neither seem to be quite right for my situation. The first suggested creating an IBPlugin, which would then mean my bindings would be available in the Bindings Inspector. I could then bind the view to the controller using IB. Apparently IBPlugins aren't supported in Xcode 4, so that one's out the window. I'm also assuming (maybe wrongly) that IBPlugins are no longer supported because there's a better way of doing such things these days?

The second option was to bind the controller to the view programmatically. I'm a bit confused as to exactly how I would achieve this. Would it require subclassing NSObjectController so I can add the calls to bind to the view? Would I need to add anything to the view to support this? Some examples I've seen say you'd need to override the bind method, and others say you don't.

Also, I've noticed that some example custom views call [self exposeBinding:@"bindingName"] in the initializer. From what I gather from various sources, this is something that's related to IBPlugins and isn't something I need to do if I'm not using them. Is that correct?

I've found a post on Stackoverflow here which seems to discuss something very similar to my problem, but there wasn't any clear winner as to the best answer. The last comment by noa on 12th Sept seems interesting, although they mention you should be calling exposeBinding:. Is this comment along the right track? Is the call to exposeBinding really necessary?

Apologies for any dumb questions. Any help greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

困倦 2024-12-21 20:47:02

第一个建议创建一个 IBPlugin,这意味着我的绑定将在绑定检查器中可用。然后我可以使用 IB 将视图绑定到控制器。显然 Xcode 4 不支持 IBPlugins,所以这是不可能的。

正确的。 Interface Builder 已死; Xcode nib 编辑器万岁(有时他们仍然称之为 Interface Builder)。

随着 IB 的消失,IBPlugins 也随之消失。

我还假设(也许是错误的)IBPlugins 不再受支持,因为现在有更好的方法来做这样的事情?

没有。

第二个选项是以编程方式将控制器绑定到视图。我对如何实现这一目标有点困惑。

发送视图 a bind:toObject:withKeyPath:options:消息

是否需要子类化 NSObjectController 以便我可以添加调用以绑定到视图?

不是 NSObjectController,而是拥有 nib 的东西(例如窗口控制器或视图控制器)或者是其中的顶级对象(例如 MainMenu nib 中的应用程序委托)。

我需要向视图添加任何内容来支持这一点吗?

见下文。

我见过的一些例子说你需要重写绑定方法,而另一些例子则说你不需要。

对于非视图(视图始终可以在不覆盖它的情况下工作),您曾经这样做过,但现在不再这样做了。您不再需要重写 bind:::: 方法。

我不知道这种情况何时发生变化,但我编写了一个测试应用程序来确认当前行为(截至雪豹和狮子)。

此外,我注意到一些示例自定义视图在初始值设定项中调用 [self次暴露Binding:@"bindingName"]。从我从各种来源收集到的信息来看,这是与 IBPlugins 相关的事情,如果我不使用它们,我就不需要做这些事情。这是正确的吗?

没有。

您不需要重写 bind:::: 来绑定到任何 KVC/KVO 兼容属性,也不需要发送 exposeBinding:

令人困惑的是,文档另有说明:即使在视图中,您也必须覆盖 bind::::unbind:,并且exposeBinding: 对任何事情都有用。

要创建可用的绑定,您所要做的就是实现符合 KVC/KVO 的属性。如果它是合成的@property,则完成。否则,请参阅此处

然后,向视图/对象发送一条 bind:::: 消息以实际绑定它,因为无法在 nib 编辑器中公开绑定。

TL;DR:

只需实现一个常规属性,您就可以将其与 a bind:toObject:withKeyPath:options: message(至少在 Snow Leopard 和 Lion 中)。您不再需要从任何地方发送 exposeBinding:。您无法使自定义绑定显示在 Xcode 4 的 nib 编辑器中。

The first suggested creating an IBPlugin, which would then mean my bindings would be available in the Bindings Inspector. I could then bind the view to the controller using IB. Apparently IBPlugins aren't supported in Xcode 4, so that one's out the window.

Correct. Interface Builder is dead; long live the Xcode nib editor (which they still call Interface Builder sometimes).

With IB gone, so are IBPlugins.

I'm also assuming (maybe wrongly) that IBPlugins are no longer supported because there's a better way of doing such things these days?

Nope.

The second option was to bind the controller to the view programmatically. I'm a bit confused as to exactly how I would achieve this.

Send the view a bind:toObject:withKeyPath:options: message.

Would it require subclassing NSObjectController so I can add the calls to bind to the view?

Not NSObjectController, but something that either owns the nib (such as a window controller or view controller) or is a top-level object inside it (such as the application's delegate in the MainMenu nib).

Would I need to add anything to the view to support this?

See below.

Some examples I've seen say you'd need to override the bind method, and others say you don't.

You used to, for non-views (views always worked without overriding it), but not anymore. You no longer need to override the bind:::: method.

I don't know when this changed, but I wrote a test app to confirm the current behavior (as of Snow Leopard and Lion).

Also, I've noticed that some example custom views call [self exposeBinding:@"bindingName"] in the initializer. From what I gather from various sources, this is something that's related to IBPlugins and isn't something I need to do if I'm not using them. Is that correct?

Nope.

You don't need to override bind:::: to bind to any KVC-/KVO-compliant property, and you don't need to send exposeBinding:.

Confusingly, the documentation says otherwise: that you must override bind:::: and unbind:, even in views, and that exposeBinding: is useful for anything.

All you have to do to create an available binding is implement a KVC-/KVO-compliant property. If it's a synthesized @property, this is done. Otherwise, see here.

Then, send the view/object a bind:::: message to actually bind it, since there's no way to expose the binding in the nib editor.

TL;DR:

Just implement a regular property, and you'll be able to bind it with a bind:toObject:withKeyPath:options: message (at least in Snow Leopard and Lion). You don't need to send exposeBinding: from anywhere anymore. You can't make custom bindings show up in the nib editor in Xcode 4.

撕心裂肺的伤痛 2024-12-21 20:47:02

为了详细说明/澄清/武断@PeterHosey的答案。我冒昧地分叉了他的测试应用程序努力阐明我能够找出绑定视图属性的唯一方法......在“现代”中(不是),后 IBPlugin (RIP) 时代...整个应用程序是通过子类 NSView 中的 3 个方法完成的,并附加了一些绑定。

在此处输入图像描述

为了让视图“更新视图”,而不必弄乱 hueDegrees 属性的 setter.. 我只是这样做...

- (void) didChangeValueForKey:(NSString*)key {
     self.needsDisplay = YES; [super didChangeValueForKey:key]; }

通过这样做,并像这样在 IB 中设置属性的初始值...

您消除了很多粘合代码。为了让“Hue”NSTextField正确更新......因为你无法“绑定”到视图......我只需在“对象”中拖动一个NSViewController区域”,并将视图控制器的View出口连接到IB中的视图。然后通过视图控制器创建绑定。

在此处输入图像描述

希望这有助于澄清 - 通过一个非常简单的解决方案 - 这个记录不充分/通常令人困惑的问题。

To elaborate on / clarify / pontificate upon @PeterHosey's answer.. i took the liberty of forking his test app in efforts to make clear the ONLY way I have been able to figure out to bind a view's properties... in the "modern" (not), Post-IBPlugin (RIP) era... The entire app is done in 3 methods in a subclassed NSView with some bindings attached.

enter image description here

In order for a view to "update the view" without having to mess around with the hueDegrees property's setter.. I just do this...

- (void) didChangeValueForKey:(NSString*)key {
     self.needsDisplay = YES; [super didChangeValueForKey:key]; }

By doing that, and setting the initial value for the property in IB like so...

enter image description here

You eliminate a lot of glue code. In order to have the "Hue" NSTextField properly update... since you can't "bind" to a view.. I simply drag an NSViewController in the "Objects area", and connect the view controller's View outlet to the view in IB. Then create your binding via the view controller.

enter image description here

Hope this helps clarify - with a quite simple solution - this poorly-documented / commonly-confused issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文