如何在没有 NSTreeController 的情况下选择 NSOutlineView 中的项目?
-
11-09-2019 - |
题
我在用着 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:
方法。如果您结合起来,与彼得有关使用上述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];
如果您还不知道,PXSourceList是一个很好的替代品的NSOutlineView,如果你正在寻找的iTunes /邮件风格轮廓。把它捡起来这里: PxSourceList
这是一个老问题,但情况仍然是相同的。至于有一个迅速的版本的请求,这是我服用。我想你应该直接与您的数据源类,而不是延长NSOutlineView交互我没有找到公认的答案为我工作。烦人的,除非他们被扩展这就是为什么它是易于使用的数据源的大纲不会找到行。以我为例,我发现,你必须扩大以相反的顺序您的项目的父母的,让你开始在顶层和对你试图扩大实际的项目工作的方式。我觉得应该建,但除非我错过了什么 - 这不是
。在本实施例中的FileItem是我的数据源集合项目类。它包含一个属性“父”,其需要是有效的,如果它是所显示的层次结构的一部分。
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)
}