我正在使用NSOutlineView
并且 NSTreeController
已经实现了我自己的数据源。选择项目的最佳方法是什么?
NSOutlineView
已经支持expandItem:
和collapseItem:
。而且我缺少一个方便的方法,例如`selectItem:。我怎样才能以编程方式做到这一点?
谢谢你。
我正在使用NSOutlineView
并且 NSTreeController
已经实现了我自己的数据源。选择项目的最佳方法是什么?
NSOutlineView
已经支持expandItem:
和collapseItem:
。而且我缺少一个方便的方法,例如`selectItem:。我怎样才能以编程方式做到这一点?
谢谢你。
当您找不到某些东西时,请记住查看超类。在这种情况下,您需要的方法之一来自 NSTableView,它是 NSOutlineView 的直接超类。
解决方案是使用获取项目的行索引rowForItem:
,如果它不是 -1(项目不可见/未找到),则使用它创建一个索引集[NSIndexSet indexSetWithIndex:]
并将该索引集传递给selectRowIndexes:byExtendingSelection:
方法。
这就是我最终的结局。建议和更正总是受欢迎的。
@implementation NSOutlineView (Additions)
- (void)expandParentsOfItem:(id)item {
while (item != nil) {
id parent = [self parentForItem: item];
if (![self isExpandable: parent])
break;
if (![self isItemExpanded: parent])
[self expandItem: parent];
item = parent;
}
}
- (void)selectItem:(id)item {
NSInteger itemIndex = [self rowForItem:item];
if (itemIndex < 0) {
[self expandParentsOfItem: item];
itemIndex = [self rowForItem:item];
if (itemIndex < 0)
return;
}
[self selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
}
@end
不,没有selectItem:
方法,但有rowForItem:
方法。如果您将其与 Peter 的selectRowIndexes:byExtendingSelection:
上述使用建议结合起来,您应该拥有所需的所有信息。
如果你真的想有一种方法来选择一个项目,我建议setSelectedItem:
为了一致性而调用它,你可以在一个类别中写这样的东西NSOutlineView
- (void)setSelectedItem:(id)item {
NSInteger itemIndex = [self rowForItem:item];
if (itemIndex < 0) {
// You need to decide what happens if the item doesn't exist
return;
}
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:itemIndex] byExtendingSelection:NO];
}
我不知道这段代码是否真的有效;我只是为了说明这个概念而删掉它。
这是我用来以编程方式选择 PXSourceList 中的项目的代码片段。
sourceList 是一个常规的 PXSouceList 对象,我想选择大纲第一组中的第二项。
NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]]; [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];
如果您还不知道,如果您正在寻找 iTunes/邮件样式大纲,PXSourceList 是 NSOutlineView 的绝佳替代品。在这里拿起它: PxSourceList
这是一个老问题,但情况还是一样。由于有一个快速版本的要求,这是我的看法。我没有找到适合我的公认答案,因为我认为您应该直接与数据源类进行交互,而不是扩展 NSOutlineView。烦人的是,大纲不会找到行,除非它们被展开,这就是使用数据源更简单的原因。就我而言,我发现您必须以相反的顺序扩展您的项目的父项,以便您从顶层开始并朝着您要扩展的实际项目前进。我觉得应该内置,但除非我错过了什么 - 它不是。
在此示例中,FileItem 是我的数据源集合项类。它包含一个属性“parent”,如果它是显示的层次结构的一部分,则该属性必须是有效的。
func selectItem(_ item: FileItem, byExtendingSelection: Bool = false) {
guard let outlineView = outlineView else { return }
var itemIndex: Int = outlineView.row(forItem: item)
if itemIndex < 0 {
var parent: FileItem? = item
var parents = [FileItem?]()
while parent != nil {
parents.append(parent)
parent = parent?.parent
}
let reversedTree = parents.compactMap({$0}).reversed()
for level in reversedTree {
outlineView.expandItem(level, expandChildren: false)
}
itemIndex = outlineView.row(forItem: item)
if itemIndex < 0 {
print("Didn't find", item)
return
}
}
print("Expanding row", itemIndex)
outlineView.selectRowIndexes(IndexSet(integer: itemIndex), byExtendingSelection: byExtendingSelection)
outlineView.scrollRowToVisible(itemIndex)
}
(这仍然是谷歌的最高结果)
斯威夫特 4.2:
您需要确保先扩展父级:
if let parent = outlineView.parent(myItem){
mapOutlineView.expandItem(parent)
}
let rowIndex = outlineView.row(forItem: myItem)
guard rowIndex != -1 else {return}
outlineView.selectRowIndexes(IndexSet(integer: rowIndex), byExtendingSelection: false)