NSOutlineView 中的 NSButton 动作没有被调用?
NSButton action in NSOutlineView not being called?
好的,所以我有一个 NSOutlineView
(通过 NSTreeController
填充)。
现在这个大纲视图是基于视图的。
我在 Table View Cell 中添加了 2 个按钮,并为它们分配了 2 个操作(就像通常所做的那样)。
但是,当我单击按钮时,其中 none 个被调用。
这是怎么回事?或者 - 更好的措辞 - 可能会发生什么?
(这绝对是一个惊喜 - 因为我一定做过超过 100 万次类似的事情......)
问题在于基于视图的大纲视图中的单元格视图实际上位于子 NIB 中。这在 IB 中没有显示,但列内的视图层次结构本身就是一个 NIB。它被归档到一个 blob 中,并嵌入到包含大纲视图的 NIB 中。
因此,您无法真正将操作、出口或绑定连接到列外的大多数对象。它基本上是 IB 中的一个错误,它甚至允许您这样做。加载子 NIB 以创建大纲视图的视图时,连接将无法正确恢复。
有几个例外。标准占位符在 NIB 中由特殊对象 ID 标识。如果将子 NIB 中的对象连接到占位符,连接将被记录为指向该特殊 ID。当大纲视图加载子 NIB 时,实际上是与填充该占位符角色的对象建立连接。应用对象是明确的;它将是实际的应用程序对象。第一响应者实际上是 nil
,因此它继续工作。不确定的是文件所有者。
您可能认为 File's Owner 是指定为外部 NIB 所有者的任何内容,但事实并非如此。加载子NIB时,大纲视图调用委托方法-outlineView:viewForTableColumn:item:
。这通常会在大纲视图上调用 -makeViewWithIdentifier:owner:
。作为该调用的第二个参数传递的所有者是子 NIB 的文件所有者。 (如果委托未实现 -outlineView:viewForTableColumn:item:
,大纲视图将其委托作为所有者传递。)
我不清楚您的大纲视图是否在您的主 NIB 或故事板中,或者,如果不在,您所指的 AppDelegate 可能是什么。但是,如果您将按钮的操作连接到非标准占位符对象的列之外的任何内容,则在加载子 NIB 时将无法正确恢复连接。即使您连接到 File's Owner,您也可能会遇到意外连接。
一些可能的解决方案:
- 你可以实施
-outlineView:viewForTableColumn:item:
;
让它正常调用 -makeViewWithIdentifier:owner:
来获取视图;如果按钮不是单元格视图本身,则通过实际单元格视图或标签上的自定义插座找到它;并将其目标设置为所需的对象(如 self
)。
- 如果大纲视图的委托实际上是所需的目标,那么您可以利用这种怪异之处
文件的所有者。将您的按钮连接到文件的所有者,即使那样
似乎不是正确的目标,它实际上可以在 运行
时间,因为大纲视图的委托通常设置为子 NIB 的所有者。您可能需要做一些修改以使 IB 允许该连接,
因为它不会认为 File's Owner 的 class 支持所需的操作方法。
- 如果您使用容器视图作为大纲单元格视图,例如
NSTableCellView
,那么你可以子class那个,执行一个动作
方法,将你的按钮连接到它,然后执行该操作
方法转发到另一个对象。你必须找到
代码中的最终目标,因为您无法连接任何出口
NSTableCellView
对外界的事物比你能做的更好
按钮的。
- 另一种方法是使用绑定来连接按钮和
以某种方式从 到
NSTableCellView
的 objectValue
。或者通过
应用程序占位符,通过其 delegate
属性。要么
类似的东西。
我遇到了同样的问题。我将我的按钮目标更改为我的 Outlineview 而不是 AppDelegate。
转到:YourXIB--> Select Your Button--> Connection Inspector--> Referencing outlet--> 将新的引用插座拖到你的 OutlineView--> Select“代表”
好的,所以我有一个 NSOutlineView
(通过 NSTreeController
填充)。
现在这个大纲视图是基于视图的。
我在 Table View Cell 中添加了 2 个按钮,并为它们分配了 2 个操作(就像通常所做的那样)。
但是,当我单击按钮时,其中 none 个被调用。
这是怎么回事?或者 - 更好的措辞 - 可能会发生什么?
(这绝对是一个惊喜 - 因为我一定做过超过 100 万次类似的事情......)
问题在于基于视图的大纲视图中的单元格视图实际上位于子 NIB 中。这在 IB 中没有显示,但列内的视图层次结构本身就是一个 NIB。它被归档到一个 blob 中,并嵌入到包含大纲视图的 NIB 中。
因此,您无法真正将操作、出口或绑定连接到列外的大多数对象。它基本上是 IB 中的一个错误,它甚至允许您这样做。加载子 NIB 以创建大纲视图的视图时,连接将无法正确恢复。
有几个例外。标准占位符在 NIB 中由特殊对象 ID 标识。如果将子 NIB 中的对象连接到占位符,连接将被记录为指向该特殊 ID。当大纲视图加载子 NIB 时,实际上是与填充该占位符角色的对象建立连接。应用对象是明确的;它将是实际的应用程序对象。第一响应者实际上是 nil
,因此它继续工作。不确定的是文件所有者。
您可能认为 File's Owner 是指定为外部 NIB 所有者的任何内容,但事实并非如此。加载子NIB时,大纲视图调用委托方法-outlineView:viewForTableColumn:item:
。这通常会在大纲视图上调用 -makeViewWithIdentifier:owner:
。作为该调用的第二个参数传递的所有者是子 NIB 的文件所有者。 (如果委托未实现 -outlineView:viewForTableColumn:item:
,大纲视图将其委托作为所有者传递。)
我不清楚您的大纲视图是否在您的主 NIB 或故事板中,或者,如果不在,您所指的 AppDelegate 可能是什么。但是,如果您将按钮的操作连接到非标准占位符对象的列之外的任何内容,则在加载子 NIB 时将无法正确恢复连接。即使您连接到 File's Owner,您也可能会遇到意外连接。
一些可能的解决方案:
- 你可以实施
-outlineView:viewForTableColumn:item:
; 让它正常调用-makeViewWithIdentifier:owner:
来获取视图;如果按钮不是单元格视图本身,则通过实际单元格视图或标签上的自定义插座找到它;并将其目标设置为所需的对象(如self
)。 - 如果大纲视图的委托实际上是所需的目标,那么您可以利用这种怪异之处 文件的所有者。将您的按钮连接到文件的所有者,即使那样 似乎不是正确的目标,它实际上可以在 运行 时间,因为大纲视图的委托通常设置为子 NIB 的所有者。您可能需要做一些修改以使 IB 允许该连接, 因为它不会认为 File's Owner 的 class 支持所需的操作方法。
- 如果您使用容器视图作为大纲单元格视图,例如
NSTableCellView
,那么你可以子class那个,执行一个动作 方法,将你的按钮连接到它,然后执行该操作 方法转发到另一个对象。你必须找到 代码中的最终目标,因为您无法连接任何出口NSTableCellView
对外界的事物比你能做的更好 按钮的。 - 另一种方法是使用绑定来连接按钮和
以某种方式从 到
NSTableCellView
的objectValue
。或者通过 应用程序占位符,通过其delegate
属性。要么 类似的东西。
我遇到了同样的问题。我将我的按钮目标更改为我的 Outlineview 而不是 AppDelegate。
转到:YourXIB--> Select Your Button--> Connection Inspector--> Referencing outlet--> 将新的引用插座拖到你的 OutlineView--> Select“代表”