服务应用程序中的 NSTableView 中不能 select 行
Can't select rows in an NSTableView in Service app
我真的快疯了。
我有一个服务应用程序可以打开一个非常简单的 NSPanel
,它由一个 NSTableView
、一个标签和三个 NSButton
控件组成。
就是这样。
table 视图是基于视图的,在 IB 中定义了四个不同的 NSTableCellView
行。
table 代码非常简单;我的 NSWindowController
子类既是数据源又是委托。在大多数情况下,一切都很完美:
- window 打开
- 预期的数据源方法(
numberOfRowsInTableView:
和
tableView:objectValueForTableColumn:row:
) 接到电话
- table 通过其视图和部分分隔符填充
tableView:isGroupRow:
和 tableView:viewForTableColumn:row:
- empty selection 被禁用,因此委托立即收到一个
tableView:shouldSelectRow:
消息,table 自动
select第一行
- table 完全按照应有的方式显示,第一行是 selected
一切看起来都很完美,但我不能 select 不同的行。我在 table 中点击的任何内容都不会改变 selection.
我试过:
- 子类化
NSTableCellView
并验证它正在接收 hitTest:
调用
- 尝试 "hacking" table 单元格视图
hitTest:
所以它总是 return nil
- 尝试了 "refuses first responder"、"enabled"、"editable" 属性在 table 单元格视图
内的控件视图上的各种组合
- 尝试删除所有控制视图。所以 table 单元格视图是空的
- 尝试实施
tableView:selectionIndexesForProposedSelection:
而不是 tableView:shouldSelectRow:
- 将
NSPanel
更改为常规 NSWindow
似乎没有任何区别。我在 table 中单击的任何内容都不会更改 selection,并且我的 table 视图委托从未收到另一个 tableView:shouldSelectRow:
调用。
请注意,window 中的所有其他 (NSButton
) 控件工作正常。我可以点击其中任何一个。
更新 #1
根据评论,我尝试将产品更改为普通的旧产品 .app
,但没有任何区别。
我的下一步是 fiddle 一些更多的委托方法并将问题缩小到:
如果我实现 tableView:shouldSelectRow:
,table 调用我的委托方法两次(因为我关闭了 "empty selection",table 必须最初确定哪一行 select 作为默认值,所以我接到了两个电话,一个是第 0 行(否),另一个是第 1 行(是))。但是,如果我点击 table,我再也不会收到另一个 tableView:shouldSelectRow:
。
如果我删除 tableView:shouldSelectRow:
的实现,table selection 会神奇地开始工作。 (除了您可以 select 对行进行分组这一事实,这很糟糕。)
还尝试实施 tableView:selectionIndexesForProposedSelection:
而不是 tableView:shouldSelectRow:
;同样的行为
因此,如果我实现任何委托方法来确定哪些行是 selectable,我就不能 select 任何行。 感叹
更新#2
我对应用程序进行了调整和重构,因此现在有一个新的视图控制器对象专门用于管理 table 视图(而不是重载 window 控制器)。所有数据模型和委托方法都已移至新的视图控制器。
此外(认为 IB 中的 table 视图可能有些奇怪),我从 NIB 中删除了 table 视图并重新创建它及其所有连接。
不幸的是,这些更改都没有产生任何影响。如果实现了 tableView:shouldSelectRow:
,那么 table 是不可用的。删掉方法,又可以了。
更新#3
它变得更奇怪了:认为我可以 "hack" 行 selection 问题,我实现了 table 视图委托方法 tableViewSelectionIsChanging:
和 tableViewSelectionDidChange:
.都没有被叫到。即使我删除 tableView:shouldSelectRow:
,允许 table selection 工作,也不会收到 tableViewSelectionIsChanging:
或 tableViewSelectionDidChange:
。
然而,如果我为 NSTableViewSelectionIsChangingNotification
和 NSTableViewSelectionDidChangeNotification
添加观察者,它们会被接收。
另请注意,作为 table 视图的委托和数据源的 NSViewController
子类明确符合 <NSTableViewDelegate>
和 <NSTableViewDataSource>
,因此不应该有任何table 视图应该混淆实现了哪些委托方法的原因。
哎呀!现在这很尴尬。
所以问题是对 window 控制器的弱引用。
事情是这样的:正在创建、加载 window 控制器,并显示 window。在初始演示和显示期间,一切正常(tableView:shouldSelectRow:
等),因为存在 window 和视图控制器。但在未来的某个事件循环中,ARC 销毁了 window 和视图控制器,只在屏幕上留下 window 和 table 视图,以及对其委托和数据源对象的弱引用现在是零。
解决方案是修复 window 控制器管理,使其保持对 window 控制器的强引用,直到 window 关闭。
有时是最简单的事情让你犯错...
我真的快疯了。
我有一个服务应用程序可以打开一个非常简单的 NSPanel
,它由一个 NSTableView
、一个标签和三个 NSButton
控件组成。
就是这样。
table 视图是基于视图的,在 IB 中定义了四个不同的 NSTableCellView
行。
table 代码非常简单;我的 NSWindowController
子类既是数据源又是委托。在大多数情况下,一切都很完美:
- window 打开
- 预期的数据源方法(
numberOfRowsInTableView:
和tableView:objectValueForTableColumn:row:
) 接到电话 - table 通过其视图和部分分隔符填充
tableView:isGroupRow:
和tableView:viewForTableColumn:row:
- empty selection 被禁用,因此委托立即收到一个
tableView:shouldSelectRow:
消息,table 自动 select第一行 - table 完全按照应有的方式显示,第一行是 selected
一切看起来都很完美,但我不能 select 不同的行。我在 table 中点击的任何内容都不会改变 selection.
我试过:
- 子类化
NSTableCellView
并验证它正在接收hitTest:
调用 - 尝试 "hacking" table 单元格视图
hitTest:
所以它总是 returnnil
- 尝试了 "refuses first responder"、"enabled"、"editable" 属性在 table 单元格视图 内的控件视图上的各种组合
- 尝试删除所有控制视图。所以 table 单元格视图是空的
- 尝试实施
tableView:selectionIndexesForProposedSelection:
而不是tableView:shouldSelectRow:
- 将
NSPanel
更改为常规NSWindow
似乎没有任何区别。我在 table 中单击的任何内容都不会更改 selection,并且我的 table 视图委托从未收到另一个 tableView:shouldSelectRow:
调用。
请注意,window 中的所有其他 (NSButton
) 控件工作正常。我可以点击其中任何一个。
更新 #1
根据评论,我尝试将产品更改为普通的旧产品 .app
,但没有任何区别。
我的下一步是 fiddle 一些更多的委托方法并将问题缩小到:
如果我实现
tableView:shouldSelectRow:
,table 调用我的委托方法两次(因为我关闭了 "empty selection",table 必须最初确定哪一行 select 作为默认值,所以我接到了两个电话,一个是第 0 行(否),另一个是第 1 行(是))。但是,如果我点击 table,我再也不会收到另一个tableView:shouldSelectRow:
。如果我删除
tableView:shouldSelectRow:
的实现,table selection 会神奇地开始工作。 (除了您可以 select 对行进行分组这一事实,这很糟糕。)还尝试实施
tableView:selectionIndexesForProposedSelection:
而不是tableView:shouldSelectRow:
;同样的行为
因此,如果我实现任何委托方法来确定哪些行是 selectable,我就不能 select 任何行。 感叹
更新#2
我对应用程序进行了调整和重构,因此现在有一个新的视图控制器对象专门用于管理 table 视图(而不是重载 window 控制器)。所有数据模型和委托方法都已移至新的视图控制器。
此外(认为 IB 中的 table 视图可能有些奇怪),我从 NIB 中删除了 table 视图并重新创建它及其所有连接。
不幸的是,这些更改都没有产生任何影响。如果实现了 tableView:shouldSelectRow:
,那么 table 是不可用的。删掉方法,又可以了。
更新#3
它变得更奇怪了:认为我可以 "hack" 行 selection 问题,我实现了 table 视图委托方法 tableViewSelectionIsChanging:
和 tableViewSelectionDidChange:
.都没有被叫到。即使我删除 tableView:shouldSelectRow:
,允许 table selection 工作,也不会收到 tableViewSelectionIsChanging:
或 tableViewSelectionDidChange:
。
然而,如果我为 NSTableViewSelectionIsChangingNotification
和 NSTableViewSelectionDidChangeNotification
添加观察者,它们会被接收。
另请注意,作为 table 视图的委托和数据源的 NSViewController
子类明确符合 <NSTableViewDelegate>
和 <NSTableViewDataSource>
,因此不应该有任何table 视图应该混淆实现了哪些委托方法的原因。
哎呀!现在这很尴尬。
所以问题是对 window 控制器的弱引用。
事情是这样的:正在创建、加载 window 控制器,并显示 window。在初始演示和显示期间,一切正常(tableView:shouldSelectRow:
等),因为存在 window 和视图控制器。但在未来的某个事件循环中,ARC 销毁了 window 和视图控制器,只在屏幕上留下 window 和 table 视图,以及对其委托和数据源对象的弱引用现在是零。
解决方案是修复 window 控制器管理,使其保持对 window 控制器的强引用,直到 window 关闭。
有时是最简单的事情让你犯错...