Как выбрать элементы в NSOutlineView без NSTreeController?
Я использую NSOutlineView
без NSTreeController
и внедрил свой собственный источник данных. Каков наилучший способ выбора элемента?
NSOutlineView
поддержка уже expandItem:
и collapseItem:
. И у меня отсутствует удобный метод, например `selectItem:. Как я могу сделать это программно?
Спасибо.
Ответы
Ответ 1
Не забудьте посмотреть в суперклассах, когда вы не можете найти что-то. В этом случае один из методов, который вам нужен, - это NSTableView, который является непосредственным суперклассом NSOutlineView.
Решение заключается в получить индекс строки для элемента с помощью rowForItem:
, а если это не -1 (элемент не отображается /not found), создать с ним индекс с [NSIndexSet indexSetWithIndex:]
и передать этот индекс, установленный в метод selectRowIndexes:byExtendingSelection:
.
Ответ 2
Вот как я, наконец, закончил. Предложения и исправления всегда приветствуются.
@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
Ответ 3
Нет, нет метода 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];
}
Я не знаю, действительно ли этот код работает; Я просто бросил его, чтобы проиллюстрировать концепцию.
Ответ 4
Вот фрагмент кода, который я использовал для программного выбора элемента в PXSourceList.
sourceList - это обычный объект PXSouceList, и мне нужно выбрать второй элемент в первой группе контура.
NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]];
[sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];
Если вы еще не знаете, PXSourceList - отличная замена NSOutlineView, если вы ищете контуры стиля itunes/mail. Возьмите его здесь:
PxSourceList
Ответ 5
Это старый вопрос, но ситуация все та же. Поскольку был запрос на быструю версию, здесь мой взять. Я не нашел приемлемый ответ для меня, так как я думаю, что вы должны напрямую взаимодействовать с вашим классом источника данных, а не расширять 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)
}