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

Cocoa NSArrayController:如何以编程方式清除选择?,cocoa,binding,nsarraycontroller,Cocoa,Binding,Nsarraycontroller,让我抓狂的非常简单的问题:以编程方式清除NSArrayController选择的正确方法是什么 我正在设计一个包含以下组件的视图: NSArrayController*controller1:绑定到对象数组 NSPOUPView视图1:绑定到controller1.arrangedObjects的内容;绑定到controller1.selection的值;选择“插入空占位符” NSArrayController*controller2:绑定到controller1.selection中存储的数

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

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

  • NSArrayController*controller1:绑定到对象数组
  • NSPOUPView视图1:绑定到controller1.arrangedObjects的内容;绑定到controller1.selection的值;选择“插入空占位符”
  • NSArrayController*controller2:绑定到controller1.selection中存储的数组
  • NSPOUPView视图2:绑定到controller2.arrangedObjects的内容;值绑定到controller2.selection;选择“插入空占位符”
最初,将填充view1的内容;controller1和controller2的选择值为零;和view1和view2显示空占位符。选择controller1会导致controller1的选择发生更改并填充view2的内容。一切都好

我想实现一个清除按钮来清除controller1的选择,由于绑定,它还应该清除controller2的选择,并将view1和view2重置为空占位符。就我个人而言,我无法为这个非常简单的函数找到合适的代码。更改控制器1的选择无法更新视图1中显示的值。更糟糕的是,以编程方式更改controller1选择会导致controller2中发生奇怪的事情:在view1中进一步选择值对view2没有任何影响

我尝试过的事情:

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

  • 使用null调用controller1的SetSelectedObject方法

  • 使用NSNotFound调用controller1的SetSelectedIndex方法

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

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


有什么想法吗?谢谢…

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

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

设置选择索引:

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

(BOOL)设置选择索引:(NSIndexSet*)索引

讨论

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

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

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

概括而言:

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

  • 使用属性“NSArray*a_list”创建应用程序。用A的一些实例填充它,并用一些b实例填充每个A实例的b_列表

  • 创建一个包含两个阵列控制器的窗口,控制器a(绑定到a_列表)和控制器B(绑定到控制器a.selection.B_列表)

  • 在窗口中创建两个弹出按钮,Popup_A(绑定到控制器_A.arrangedObjects)和Popup_B(绑定到控制器_B.arrangedObjects)

  • 创建一个带有某些逻辑的“清除”按钮,以清除控制器a的选择。(“某些逻辑”是Apple文档中推荐的方法或任何其他方法。)

  • 运行应用程序。在Popup_A中选择一个条目。请注意,Popup_B将填充Controller_A.selection.B_列表的实例

  • 现在点击清除按钮

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

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

我的解决方法是不直接将任何内容绑定到B_控制器选择。相反,以编程方式访问B_控制器,并查看A_控制器的选择值,如下所示:

// 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]];

我还向苹果公司提交了一份包含这些信息的bug报告。

回答了一个非常老的问题,但仍然是

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

[arrayController setAvoidsEmptySelection:NO];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:
    NSMakeRange(NSNotFound, 0)];
[arrayController setSelectionIndexes:indexes];
根据这一点,可以使用SetSelectionIndex完成:

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

目标C:

[arrayController设置选择索引:[NSIndexSet indexSet]]

斯威夫特:


arrayController.SetSelectionIndex(NSIndexSet())

这就是苹果的设置方式,所以我不认为它真的那么难看——如果在表没有选择的情况下记录selectionIndex,这就是你得到的(它实际上只是打印出一个非常大的数字,但我认为这正是NSIntegerMax的功能)。在控制器B上,你在用电话吗