Я могу получить экземпляр NSBrowser для отображения правильных данных в первом столбце. Однако, когда я выбираю один из параметров, следующий столбец просто отображает один и тот же набор параметров. Я прочитал документы, посмотрел на соответствующий примерный пример кода Apple и почти все, что мог найти в Интернете, но я просто не могу понять правильный способ реализации необходимых методов. Данные, которые я предоставляю браузеру, представляют собой набор словарей. Каждый словарь, в свою очередь, содержит «детский» ключ, который является еще одним массивом словарей. И эти словари имеют свои собственные «ребенок» ключ, также являются массивами словарей и т.д. Использование JSON для описательных целей (объекты словарей, массивы массивы), это выглядит следующим образом:Проблемы с внедрением протокола NSBrowserDelegate
data = [
{
name: 'David',
children:[
{
name: 'Sarah',
children: {...}
},
{
name: 'Kevin',
children: {...}
}
]
},
{
name: 'Mary',
children:[
{
name: 'Greg',
children: {...}
},
{
name: 'Jane',
children: {...}
}
]
}
]
Так первая колонка должен показать «Дэвид» и «Мэри». Если выбран «Давид», следующий столбец должен показывать «Сара» и «Кевин» и т. Д.
Моя текущая реализация основана на пользовательском методе, который я создал, который должен переводить указательный путь браузера на соответствующий уровень NSArray из предоставленных данных. Этот метод выглядит следующим образом:
- (NSArray *)getSelectionInBrowser:(NSBrowser *)browser
{
NSArray *selection = browserData;
NSIndexPath *path = [browser selectionIndexPath];
for (NSUInteger i = 0; i < path.length; i++) {
selection = [[selection objectAtIndex:i] objectForKey:@"children"];
}
return selection;
}
Моя реализация требуемых методов NSBrowserDelegate протокола выглядит следующим образом:
- (NSInteger)browser:(NSBrowser *)sender numberOfRowsInColumn:(NSInteger)column
{
return [[self getSelectionInBrowser:sender] count];
}
- (NSInteger)browser:(NSBrowser *)browser numberOfChildrenOfItem:(id)item {
return [[self getSelectionInBrowser:browser] count];
}
- (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item {
return [self getSelectionInBrowser:browser];
}
- (BOOL)browser:(NSBrowser *)browser isLeafItem:(id)item {
return ![item isKindOfClass:[NSMutableArray class]];
}
- (id)browser:(NSBrowser *)browser objectValueForItem:(id)item {
return nil;
}
- (void)browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(NSInteger)row column:(NSInteger)column {
NSArray *selection = [self getSelectionInBrowser:browser];
cell.title = [[selection objectAtIndex:row] objectForKey:@"name"];
}
Первый столбец NSBrowser заполняется с правильными именами. Однако, как только я делаю выбор, программа вылетает с ошибкой -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 0]
. После некоторой отладки строка кода, с которой он падает, - это вызов objectAtIndex:
в моем обычном getSelectionInBrowser:
.
Это меня не удивляет, потому что еще до крушения я понял, что делаю что-то неправильно, полагаясь на этот пользовательский метод, чтобы получить текущий выбор. Я полагаю, что эта работа должна быть выполнена в самих методах делегата, и при правильной реализации текущий выбор должен быть доступен в переменной item
, которая предоставляется во многих из этих методов. Однако я не мог заставить это работать. Переменная item
всегда представляла собой просто корневой объект данных, а не отражала наиболее «развернутый» выбор.
Итак, как мне исправить мою реализацию?
Люди из будущего благодарит вас за помощь. –