【问题标题】:NSButton action in NSOutlineView not being called?NSOutlineView 中的 NSButton 动作没有被调用?
【发布时间】:2015-10-16 00:23:18
【问题描述】:

好的,所以我有一个NSOutlineView(通过NSTreeController 填充)。

现在这个大纲视图是基于视图的。

我在表格视图单元格中添加了 2 个按钮,并为它们分配了 2 个操作(通常会这样做)。

但是,当我单击按钮时,它们都没有被调用。

发生了什么事?或者 - 更好的措辞 - 可能会发生什么?


(这绝对是一个惊喜 - 因为我一定做过超过 100 万次类似的事情......)

【问题讨论】:

  • 按钮的目标是什么?
  • @KenThomases 我期待这个问题:) 但是......不,这不是“我以编程方式创建按钮并忘记设置目标”的情况之一。目标是 AppDelegate(因为它是 100% 的窗口控件)。除了NSOutlineView 内部的按钮之外,它们中的每一个都有效。
  • IIRC 这些按钮的目标必须是 OutlineView 委托。所以我在我的应用程序中做了它并且它有效。我现在将目标(在 IB 中)更改为 AppDelegate(相同的操作名称)并且未调用该操作。我不知道我在哪里读到如何在基于视图的大纲视图中使用按钮。但是有一些文字。

标签: objective-c macos cocoa nsoutlineview


【解决方案1】:

问题在于基于视图的大纲视图中的单元格视图实际上位于子 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 类支持所需的操作方法。
  • 如果您使用容器视图作为大纲单元格视图,例如 NSTableCellView,然后你可以继承它,实现一个动作 方法,将您的按钮连接到该按钮,然后执行该操作 方法转发到另一个对象。你必须找到 代码中的最终目标,因为您无法连接 NSTableCellView 对外部对象比你更好 按钮。
  • 另一种方法是使用绑定来连接按钮和 以某种方式通过 NSTableCellViewobjectValue。或者通过 应用程序占位符,通过其delegate 属性。要么 类似的东西。

【讨论】:

  • 太棒了。非常感谢您的回答和解释。我无法想象这一切......(给我一些时间尝试一下,我会告诉你进展如何)真的,感谢抽出时间并伸出援助之手! ;-)
  • 太棒了。是的,它确实奏效了。我真的希望每个在这个非常奇怪的问题上苦苦挣扎的人都能看到你的答案。非常感谢! :)
【解决方案2】:

我遇到了同样的问题。我将按钮目标更改为 Outlineview 而不是 AppDelegate。

转到:YourXIB--> 选择您的按钮--> Connection Inspector--> 引用出口--> 将新的引用出口拖到您的 OutlineView--> 选择“委托”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 2019-08-08
    • 1970-01-01
    • 2017-09-26
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多