Источник данных NSOutlineView не позволяет расширять - PullRequest
0 голосов
/ 26 июня 2011

У меня есть NSOutlineView, в который я пытаюсь загрузить массив объектов модели в качестве источника данных.

В частности, объекты модели вместе с кучей свойств верхнего уровня (например, заголовок,и т.д.) имеют BOOLEAN NSNumber, который указывает, есть ли у них дочерний элемент (isRoute), вместе со свойством массива, которое фактически содержит указанные дочерние элементы (которые, фактически, являются экземплярами того же класса модели).

@interface RoadModel : NSObject {

    NSString *_id;
    NSString *roadmapID;
    NSString *routeID;

    NSString *title;
    NSString *description;
    NSNumber *collapsed;
    NSNumber *isRoute;
    NSString *staff;
    NSNumber *start;

    NSArray *staffList;
    NSMutableArray *updates;
    NSMutableArray *uploads;
    NSMutableArray *children;
    NSNumber *childrenCount;

}

@property (nonatomic, copy) NSString *_id;
@property (nonatomic, copy) NSString *roadmapID;
@property (nonatomic, copy) NSString *routeID;

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *description;
@property (nonatomic, copy) NSNumber *collapsed;
@property (nonatomic, copy) NSNumber *isRoute;
@property (nonatomic, copy) NSString *staff;
@property (nonatomic, copy) NSNumber *start;

@property (nonatomic, copy) NSArray *staffList;
@property (nonatomic, copy) NSMutableArray *updates;
@property (nonatomic, copy) NSMutableArray *uploads;
@property (nonatomic, copy) NSMutableArray *children;
@property (nonatomic, copy) NSNumber *childrenCount;

- (id)initWithJSONObject:(NSDictionary *)JSONObject;

Это интерфейс для объекта модели.

Теперь в конкретном контроллере представления я создаю экземпляр NSOutlineView и настраиваю его источник данных с массивом этих объектов в методе init (root = roads).Вот реализация источника данных.

@implementation RoadOutlineViewDataSource

- (id)initWithRoads:(NSArray *)roads {

    if (self = [super init])
        root = roads;

    return self;

}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {

    if (item == nil)
        return [root count];

    else {
        NSLog(@"ROUTE HAS CHILDREN");
        return [[item childrenCount] intValue];
    }
    return 0; 
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    if (item == nil)
        return YES;

    return [[item isRoute] boolValue];

}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {

    if (item == nil) {
        return [root objectAtIndex:index];
    } else {
        return [((RoadModel *)item).children objectAtIndex:index];
    }
    return nil;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {

    return [item title];

}

@end

Теперь, когда меня сбивают с толку, это то, что второй метод, в котором источник данных пытается выяснить, сколько дочерних элементов у каждого элемента, вызывается толькоодин раз, для корневого массива.Он даже не пытается запросить каждый из элементов модели в корне, поэтому я получаю по строке для каждого объекта модели, но те, которые должны быть расширяемыми, не являются.

Для интереса я реализовал метод делегата, который по-разному рисует «расширяемые» строки, и это работает просто отлично.Однако что-то в этой реализации заставляет источник данных не запрашивать каждый элемент, если у него есть дочерние элементы, и поэтому я не могу развернуть те элементы, которые должны быть расширены.Я не знаю почему, хотя!Я следил за документами Apple и кучей онлайн-ресурсов, но продолжаю сталкиваться с этой же проблемой.Любой совет будет высоко ценится.Спасибо всем.

РЕДАКТИРОВАТЬ:

Вот как я настраиваю OutlineView

NSOutlineView *outlineView = [[NSOutlineView alloc] initWithFrame:self.frame];
    NSTableColumn *titleColumn = [[NSTableColumn alloc] initWithIdentifier:@"title"];
    [titleColumn setWidth:self.frame.size.width];
    [outlineView addTableColumn:titleColumn];
    [outlineView setRowHeight:22.0f];
    [outlineView setIndentationPerLevel:5.0];
    [outlineView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
    [outlineView setUsesAlternatingRowBackgroundColors:YES];
    [outlineView setGridStyleMask:NSTableViewDashedHorizontalGridLineMask];
    [scrollView setDocumentView:outlineView];
    RoadOutlineViewDelegate *delegate       = [[RoadOutlineViewDelegate alloc] init];
    RoadOutlineViewDataSource *dataSource   = [[[RoadOutlineViewDataSource alloc] initWithRoads:roads] retain];
    [outlineView setDataSource:dataSource];
    [outlineView setDelegate:delegate];
    [outlineView reloadData];

1 Ответ

3 голосов
/ 26 июня 2011

Я думаю, что проблема в вашем -outlineView:isItemExpandable: методе делегата. Это также вызывается для вашего корневого объекта, поэтому вам нужно вернуть YES, если элемент, переданный этому методу, равен nil.

Кроме того, ваш источник данных намеренно поддерживает слабую ссылку на массив roads? Если нет, то «дороги» будут освобождены, потому что вы не сохраните их в своем методе -init.

...