简体   繁体   English

未调用 NSOutlineView 中的 NSButton 操作?

[英]NSButton action in NSOutlineView not being called?

OK, so I have an NSOutlineView (populated via NSTreeController ).好的,所以我有一个NSOutlineView (通过NSTreeController填充)。

Now this Outline View is View-based.现在这个大纲视图是基于视图的。

I've added 2 buttons inside the Table View Cell and assigned them 2 actions (as one would normally do).我在表格视图单元格中添加了 2 个按钮,并为它们分配了 2 个操作(通常会这样做)。

However, none of them is being called when I click the buttons.但是,当我单击按钮时,它们都没有被调用。

What is going on?到底是怎么回事? Or - better phrased - what could be going on?或者 - 更好的措辞 -发生什么?


(This one definitely came as a surprise - since I must have done similar things more than 1 million times...) (这绝对是一个惊喜——因为我一定做过超过 100 万次类似的事情......)

The problem is that the cell views in a view-based outline view are actually in a sub-NIB.问题是基于视图的大纲视图中的单元格视图实际上位于子 NIB 中。 This isn't shown in IB, but the view hierarchy inside a column is a NIB unto itself.这在 IB 中没有显示,但列内的视图层次结构本身就是一个 NIB。 It's archived into a blob and that's embedded in the NIB that contains the outline view.它被归档到一个 blob 中,并嵌入到包含大纲视图的 NIB 中。

Because of that, you can't really connect actions, outlets, or bindings to most of the objects outside of the column.因此,您无法真正将操作、出口或绑定连接到列外的大多数对象。 It's basically a bug in IB that it even allows you to do this.这基本上是 IB 中的一个错误,它甚至允许您这样做。 The connections won't be restored properly when the sub-NIB is loaded to create views for the outline view.当加载子 NIB 以创建大纲视图的视图时,连接将无法正确恢复。

There are a couple of exceptions.有几个例外。 The standard placeholders are identified in a NIB by special object IDs.标准占位符在 NIB 中由特殊对象 ID 标识。 If you connect an object in a sub-NIB to a placeholder, the connection is recorded as being to that special ID.如果将子 NIB 中的对象连接到占位符,则该连接将被记录为该特殊 ID。 When the sub-NIB is loaded by the outline view, the connection is actually made to the object which fills the role for that placeholder.当大纲视图加载子 NIB 时,实际上会连接到为该占位符填充角色的对象。 The application object is unambiguous;应用对象明确; it will be the actual application object.它将是实际的应用程序对象。 The first responder is actually nil , so that continues to work.第一响应者实际上是nil ,所以它继续工作。 The iffy one is File's Owner.不确定的一个是文件的所有者。

You might think that File's Owner is whatever was specified as the owner of the outer NIB, but that's not so.您可能认为 File's Owner 是指定为外部 NIB 所有者的任何内容,但事实并非如此。 When the sub-NIB is loaded, the outline view calls the delegate method -outlineView:viewForTableColumn:item: .加载子 NIB 时,大纲视图调用委托方法-outlineView:viewForTableColumn:item: That normally calls -makeViewWithIdentifier:owner: on the outline view.通常在大纲视图上调用-makeViewWithIdentifier:owner: The owner passed as the second parameter of that call is what serves as the File's Owner for the sub-NIB.作为该调用的第二个参数传递的所有者是子 NIB 的文件所有者。 (If the delegate doesn't implement -outlineView:viewForTableColumn:item: , the outline view passes its delegate as the owner.) (如果委托未实现-outlineView:viewForTableColumn:item: ,则大纲视图将其委托作为所有者传递。)

It's not clear to me if your outline view is in your main NIB or storyboard or, if not, what the AppDelegate you refer to might be.我不清楚您的大纲视图是否在您的主要 NIB 或故事板中,或者如果不是,您所指的 AppDelegate 可能是什么。 But if you're connecting your button's action to anything outside of the column that's not a standard placeholder object, the connection won't be restored properly when the sub-NIB is loaded.但是,如果您将按钮的操作连接到列之外的任何非标准占位符对象,则在加载子 NIB 时将无法正确恢复连接。 And even if you connect to File's Owner, you may get an unexpected connection.即使您连接到 File's Owner,也可能会出现意外连接。

A few possible solutions:几个可能的解决方案:

  • You could implement -outlineView:viewForTableColumn:item: ;你可以实现-outlineView:viewForTableColumn:item: ; have it call -makeViewWithIdentifier:owner: as normal to get the view;让它像往常一样调用-makeViewWithIdentifier:owner:来获取视图; if the button isn't the cell view itself, find it via custom outlets on the actual cell view or a tag;如果按钮不是单元格视图本身,请通过实际单元格视图或标签上的自定义插座找到它; and set its target to the desired object (like self ).并将其目标设置为所需的对象(如self )。
  • If the outline view's delegate actually is the desired target, then you can take advantage of the weirdness with File's Owner.如果大纲视图的委托实际上是所需的目标,那么您可以利用 File's Owner 的奇怪之处。 Connect your button to File's Owner even though that doesn't seem like the right target and it will actually work at run time because the outline view's delegate is typically set as the owner of the sub-NIB.将您的按钮连接到 File's Owner,即使这看起来不是正确的目标,它实际上会在运行时工作,因为大纲视图的委托通常被设置为子 NIB 的所有者。 You may need to do some hacks to make IB allow that connection, because it won't think that the class of File's Owner supports the desired action method.您可能需要做一些 hack 来让 IB 允许该连接,因为它不会认为 File's Owner 类支持所需的操作方法。
  • If you're using a container view as your outline cell view, such as NSTableCellView , then you can subclass that, implement an action method on it, connect your button to that, and have that action method forward along to another object.如果您使用容器视图作为大纲单元格视图,例如NSTableCellView ,那么您可以将其子类化,在其上实现一个操作方法,将您的按钮连接到该视图,然后将该操作方法转发到另一个对象。 You'll have to find the ultimate target in code because you can't connect any outlets of NSTableCellView to outside objects any better than you can the button's.您必须在代码中找到最终目标,因为您无法将NSTableCellView任何插座连接到外部对象,而不是按钮。
  • Another approach would be to use bindings to connect the button and go through NSTableCellView 's objectValue somehow.另一种方法是使用绑定来连接按钮并以某种方式通过NSTableCellViewobjectValue Or go through the application placeholder, via its delegate property.或者通过应用程序占位符,通过其delegate属性。 Or something like that.或类似的东西。

I faced same issue.我遇到了同样的问题。 I changes my button target to to my Outlineview's instead of AppDelegate.我将按钮目标更改为我的 Outlineview 而不是 AppDelegate。

Go to: YourXIB--> Select Your Button--> Connection Inspector--> Referencing outlet--> Drag New referencing outlet to your OutlineView--> Select "delegate"转到: YourXIB--> 选择您的按钮--> 连接检查器--> 引用插座--> 将新引用插座拖到您的 OutlineView--> 选择“委托”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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