Как выбрать элементы в NSOutlineView без NSTreeController?
-
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 / mail.Возьми это здесь:PxSourceList Список источников
Это старый вопрос, но ситуация все та же.Поскольку был запрос на версию swift, вот мое мнение.Я не нашел приемлемого ответа, который работал бы для меня, поскольку я думаю, что вы должны напрямую взаимодействовать со своим классом источника данных, а не расширять 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)
}