2014-10-12 4 views
2

Я пишу небольшое приложение, предварительно называемое «CocoaMix», целью которого является проверка кода, который я написал для доступа иерархию доступности для различных пользовательских интерфейсов. По существу, что я пытаюсь выполнить, это NSOutlineView слева и «пример» справа от тестового пользовательского интерфейса.NSOutlineView - возвращается значение объекта, но отображается только заголовок заполнителя «Table View Cell»

До сих пор для реализации источника данных у меня есть:

@interface CMTopLevelCategory : NSObject 

@property (readonly) NSString *name; 

@property (readonly) NSArray *examples; 

- (id)initWithName:(NSString *)name examples:(NSArray *)examples; 

@end 


@interface CMExample : NSObject 

@property (readonly) NSString *name; 

- (id)initWithName:(NSString *)name; 

@end 


@interface CMSideOutlineViewDataSource : NSObject <NSOutlineViewDataSource> 

@end 


//... 


#define CMNameColumnIdentifier @"name" 
#define CMCountColumnIdentifier @"count" 

@interface CMSideOutlineViewDataSource() 

@property NSArray *topLevelCategories; 

@end 

@implementation CMSideOutlineViewDataSource 

- (id)init { 
    self = [super init]; 
    if (self) { 
     CMExample *largeTableExample = [[CMExample alloc] initWithName:@"Large Table"]; 
     CMTopLevelCategory *tablesCategory = [[CMTopLevelCategory alloc] initWithName:@"Tables" examples:@[ largeTableExample ]]; 

     _topLevelCategories = @[ tablesCategory ]; 
    } 
    return self; 
} 

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { 
    if (item) { 
     if ([item isKindOfClass:CMTopLevelCategory.class]) { 
      CMTopLevelCategory *topLevelCategory = item; 
      return [topLevelCategory.examples objectAtIndex:index]; 
     } 
    } else { 
     return [self.topLevelCategories objectAtIndex:index]; 
    } 
    return nil; 
} 

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { 
    return [item isKindOfClass:CMTopLevelCategory.class]; 
} 

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { 
    if (item) { 
     if ([item isKindOfClass:CMTopLevelCategory.class]) { 
      CMTopLevelCategory *topLevelCategory = item; 
      return [topLevelCategory.examples count]; 
     } 
    } else { 
     return [self.topLevelCategories count]; 
    } 
    return 0; 
} 

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    if ([item isKindOfClass:CMTopLevelCategory.class]) { 
     CMTopLevelCategory *topLevelCategory = item; 
     if ([tableColumn.identifier isEqualToString:CMNameColumnIdentifier]) { 
      return topLevelCategory.name; 
     } else if ([tableColumn.identifier isEqualToString:CMCountColumnIdentifier]) { 
      return [NSNumber numberWithUnsignedInteger:[topLevelCategory.examples count]]; 
     } 
    } else if ([item isKindOfClass:CMExample.class]) { 
     CMExample *example = item; 
     if ([tableColumn.identifier isEqualToString:CMNameColumnIdentifier]) { 
      return example.name; 
     } 
    } 
    return @"default value"; 
} 

@end 

Чтобы объяснить это, элементы верхнего уровня должны быть категориями примеров как «Таблица», а затем для каждой категории идут для некоторых примеров пользовательских интерфейсов (например, «Большая таблица» в примерах «Таблицы»).

Когда я построить и запустить, точки останова, которые я поставил в outlineView:objectValueForTableColumn:byItem: срабатывают, но текст в NSOutlineView по-прежнему заполнитель «ячейки таблицы View» Текст:

Screenshot of the "CocoaMix" application window

Что я делаю неправильно?

+0

Является ли это обзорным видом на основе представления? Какова субъектность представления для каждой ячейки таблицы? Например, является ли ячейка представлением экземпляра 'NSTableCellView', содержащего' NSTextField'? Или это просто голый «NSTextField»? Вы настроили привязки в под иерархии ячеек таблицы? Если да, объясните привязки, которые вы настроили. –

ответ

4

Я собираюсь сделать некоторые догадки. Вероятно, вы используете представление на основе представления. Вид ячеек, вероятно, NSTableCellView s с NSTextField в каждом.

В представлении схемы берется значение объекта, возвращаемое вашим источником данных из его метода -outlineView:objectValueForTableColumn:byItem:, и оно вызывает -setObjectValue: в представлении ячейки, если оно отвечает на этот метод. NSTableCellView.

Итак, теперь ваш вид на ячейку таблицы имеет свой набор objectValue. Что это делает? Возможно, ничего.

Вы можете использовать привязки для привязки подзонов к виду ячейки таблицы, с ключами, которые проходят через objectValue. Таким образом, вы можете привязать привязку Value вашего текстового поля к виду ячейки таблицы с помощью пути ключа objectValue. Это приведет к тому, что текстовое поле покажет значение.

Другой подход относится к подклассу NSTableCellView и использует этот пользовательский подкласс в качестве представления ячейки в виде контура. Затем переопределите -setObjectValue: и, в дополнение к вызову до super, вы можете передать значение объекта в subviews. Чтобы получить доступ к подзонам, вы можете подключить их к стандартным выводам textField и imageViewNSTableCellView, или вы могли бы добавить дополнительные выходы в свой собственный подкласс, подключить их в IB и использовать их.

Я считаю, что привязки привязываются легче всего. Кроме того, он обеспечивает большую гибкость. Ваша реализация -outlineView:objectValueForTableColumn:byItem: может просто вернуть item. Затем привязка вашего текстового поля может использовать objectValue.name в качестве пути ключа модели. Если вы добавите дополнительные подпункты, они могут использовать разные ключевые пути для отображения разных аспектов элемента.

Для разных столбцов вы должны использовать разные иерархии ячеек сокетов, а привязки подзапросов этих объектов будут использовать разные пути ключей, но то же самое objectValue. Идея состоит в том, что строка представляет заданный элемент, поэтому objectValue будет этим элементом, а столбцы будут использовать только разные свойства из элемента.

Другой возможный подход, если вы уверены, что ваш контурный вид будет иметь только текстовые поля в представлениях ячеек, не должен использовать NSTableCellView (или подкласс) вообще. Вместо этого используйте голые NSTextField s для просмотра сотовой ячейки. В этом случае, когда представление схемы вызывает -setObjectValue: в представлении соты, это будет текстовое поле (которое отвечает на этот метод) и установит его значение без дополнительных шагов.

+0

Спасибо за это! Я не понимаю все это прямо сейчас (я просто изучаю Какао), но я думаю, что это отвечает на мой вопрос. Да, представления ячеек выглядят как 'NSTableCellView' с 'NSTextField' в каждом. Это было создано для меня Interface Builder. –

+0

В контуре документа Interface Builder для каждого столбца у меня был «вид таблицы ячеек», содержащий «Table View Cell». Я перетащил «Table View Cell» из-под «Просмотр ячеек таблицы» и сделал его прямым дочерним элементом объекта-столбца. Затем я удалил «Просмотр ячейки таблицы». Это сработало! Я думаю, что это последний подход, о котором вы говорили: использование bare 'NSTextField'. –

+0

Yup. Я рад, что ты заработал. –

1

Измените режим содержимого NSOutlineView на ячейку на основе объяснения JAWZapps here.