【问题标题】:NSOutlineView Data Source Doesn't Allow ExpandingNSOutlineView 数据源不允许扩展
【发布时间】:2011-09-22 19:34:23
【问题描述】:

我有一个 NSOutlineView,我试图将一个模型对象数组加载到其中作为数据源。

特别是,模型对象以及一堆顶级属性(如标题等)具有一个布尔值 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 方法(根 = 道路)中使用这些对象的数组设置它的数据源。下面是dataSource的实现。

@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];

【问题讨论】:

  • 更多信息:numberOfChildrenItem: 似乎只被调用了两次,两次都被发送一个 nil 对象。
  • 配置后是否在大纲视图上调用-reloadData
  • 我进行了编辑以显示我如何设置大纲视图,其中包括调用 -reloadData
  • 更重要的是,我的实现是尽我所能,完全按照书本!

标签: objective-c cocoa macos nsoutlineview


【解决方案1】:

我认为问题在于您的 -outlineView:isItemExpandable: 委托方法。这也是为您的根对象调用的,因此如果传递给此方法的项目是nil,则需要返回YES

另外,您的数据源是否故意维护对roads 数组的弱引用?如果没有,那么“道路”将被释放,因为您没有在您的 -init 方法中保留它。

【讨论】:

  • 不幸的是,这似乎无法解决问题。不过,我会更新我上面的条目以包含您的建议!
  • 我现在确保保留了 road 数组。但问题仍然存在。孩子的数量仍然打开,y 调用了两次,都是 nil 对象。
  • 我发现 isItemExpandable 没有被调用,除非我单击一行。你知道为什么会这样吗?
  • +1 帮助我。事实上,我发现了这个问题,这与数据源无关,我怀疑这完全没问题。在最后一段代码中,您会注意到我从未设置outlineView 列。我觉得自己像个白痴。但至少现在我再也不会犯同样的错误了!
猜你喜欢
  • 2018-04-02
  • 1970-01-01
  • 2021-04-08
  • 2022-11-26
  • 1970-01-01
  • 2019-03-06
  • 2016-03-10
  • 1970-01-01
  • 2023-03-23
相关资源
最近更新 更多