4

让我发疯的非常简单的问题:以编程方式清除 NSArrayController 选择的正确方法是什么?

我正在设计一个包含以下组件的视图:

  • NSArrayController *controller1:绑定到对象数组
  • NSPopUpView view1:绑定到controller1.arrangedObjects的内容;绑定到 controller1.selection 的值;选择“插入空占位符”
  • NSArrayController *controller2:绑定到存储在controller1.selection中的数组
  • NSPopupView view2:绑定到controller2.arrangedObjects的内容;绑定到 controller2.selection 的值;选择“插入空占位符”

最初,view1 的内容被填充;controller1 和 controller2 的选择值为零;并且 view1 和 view2 显示空占位符。选择控制器 1 会导致控制器 1 的选择发生变化并填充视图 2 的内容。都好。

我想实现一个清除按钮来清除控制器 1 的选择,由于绑定,它还应该清除控制器 2 的选择并将 view1 和 view2 重置为空占位符。对于我的生活,我无法为这个非常简单的功能找出正确的代码。更改控制器 1 的选择无法更新 view1 中显示的值。更糟糕的是,以编程方式更改控制器 1 的选择会导致控制器 2 中发生奇怪的事情:视图 1 中值的进一步选择无法对视图 2 产生任何影响。

我尝试过的事情:

  • 使用 [NSArray new] 调用 controller1 的 SetSelectedObjects 方法。

  • 使用 null 调用 controller1 的 SetSelectedObjects 方法。

  • 使用 NSNotFound 调用 controller1 的 SetSelectedIndex 方法。

  • 使用 controller1 的 SelectedIndex 属性调用 controller1 的 RemoveSelectedIndex 方法。

  • 在 Cocoa NSArrayController 文档中查找任何用于清除选择值的类方法或建议。那里什么都没有——甚至没有提到这是可取的,更不用说如何实现它了。

有任何想法吗?谢谢...

4

4 回答 4

4

根据Apples Developer 文档,这可以使用 setSelectionIndexes 来完成:

要取消选择所有索引,请传递一个空索引集。

目标-C:

[arrayController setSelectionIndexes:[NSIndexSet indexSet]];

迅速:

arrayController.setSelectionIndexes( NSIndexSet() )

于 2015-05-21T18:18:54.650 回答
2

试试 controller1.selectionIndex = NSIntegerMax; 看看这是否有效。我做了一个简单的测试,标签绑定到数组控制器的选择,当我将 selectionIndex 设置为 NSIntegerMax 时,标签中显示了无选择占位符。

于 2012-08-23T04:55:56.983 回答
1

事实证明,NSArrayController 页面确实包含一个清除选择的建议:

设置选择索引:

设置接收者的选择索引并返回一个布尔值,指示选择是否改变。

(BOOL) setSelectionIndexes: (NSIndexSet *) 索引

讨论

尝试更改选择可能会导致提交编辑消息失败,从而拒绝选择更改。

要选择所有接收者的对象,索引应该是索引为 [0...count -1] 的索引集。要取消选择所有索引,请传递一个空索引集。

但是,我实际上已经尝试过,它仍然给我留下了一个问题。

概括:

  • 创建两个类,A 和 B,其中 A 包含一个属性“NSArray *b_list”,其中包含 B 的实例列表。

  • 创建一个具有“NSArray *a_list”属性的应用程序。用一些 A 实例填充它,并用一些 B 实例填充每个 A 实例的 b_list。

  • 创建一个包含两个数组控制器的窗口,Controller_A(绑定到 a_list)和 Controller_B(绑定到 Controller_A.selection.b_list)。

  • 在窗口中创建两个弹出按钮,Popup_A(绑定到Controller_A.arrangedObjects)和Popup_B(绑定到Controller_B.arrangedObjects)。

  • 使用一些逻辑创建一个“清除”按钮以清除对 Controller_A 的选择。(“某些逻辑”是 Apple 文档中推荐的方法,或任何其他方法。)

  • 运行应用程序。在 Popup_A 中选择一个条目。请注意,Popup_B 填充了 Controller_A.selection.b_list 的实例,正如它应该的那样。

  • 现在点击清除按钮。

错误:请注意,虽然 Popup_A 的内容和选择正确地变为空,但在 Popup_B 中不会发生同样的情况:它显示一个带有单个选定(空白)项目的空白条目。另请注意,Controller_B 的选择属性表示存在选择,但它的属性很奇怪:selectedIndex 指向 0 而不是 NSNotFound,并且 selectedIndexes 包含一个非空的选择整数范围。

这显然是绑定逻辑的错误,肯定会导致一些异常和逻辑错误。例如,如果有任何类型的绑定附加到 B_controller.selection,清除 A_controller 将引发与 B_controller 中的选择值相关的异常,因为它指示选择但指向垃圾。

我的解决方法是不要将任何内容直接绑定到 B_controller 选择。相反,以编程方式访问 B_controller,并鉴于 A_controller 的选择值,如下所示:

// setting some property c to the value of b_controller:
if ((B_controller.selectedIndex == NSNotFound) || A_controller.selectedIndex == NSNotFound))
    c = nil;
else
    c = [B_controller objectAtIndex: [B_controller.selectedIndex]];

我还将使用此信息向 Apple 提交错误报告。

于 2012-08-24T16:39:20.703 回答
1

回答一个非常古老的问题,但仍然如此。

我只需要同样的东西,对我来说这很有效:

[arrayController setAvoidsEmptySelection:NO];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:
    NSMakeRange(NSNotFound, 0)];
[arrayController setSelectionIndexes:indexes];
于 2014-07-04T07:17:39.330 回答