NSArrayController:如何以编程方式清除选择?

时间:2012-08-22 23:12:44

标签: cocoa binding nsarraycontroller

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

我正在使用以下组件设计视图:

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

最初,填充了view1的内容; controller1和controller2具有零选择值;和view1和view2显示空占位符。选择controller1会导致controller1的选择发生变化,并且view2的内容将被填充。一切都好。

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

我尝试过的事情:

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

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

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

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

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

有什么想法吗?感谢...

4 个答案:

答案 0 :(得分:4)

根据Apples Developer documentation,可以使用setSelectionIndexes:

完成
  

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

目标-C:

[arrayController setSelectionIndexes:[NSIndexSet indexSet]];

夫特:

arrayController.setSelectionIndexes( NSIndexSet() )

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

  

setSelectionIndexes:

     

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

     

(BOOL)setSelectionIndexes:(NSIndexSet *)索引

     

讨论

     

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

     

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

然而,我实际上已经尝试过,但它仍然让我遇到了问题。

概括:

  • 创建两个类A和B,其中A包含属性" NSArray * b_list"其中包含B&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提交了错误报告。

答案 3 :(得分:1)

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

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

[arrayController setAvoidsEmptySelection:NO];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:
    NSMakeRange(NSNotFound, 0)];
[arrayController setSelectionIndexes:indexes];