从数据源加载数据的NSOutlineView展开所有项目

5

首先,我是新手cocoa开发者,所以我想我可能在尝试错误的方法,但是还是来试一下:

我有一个NSOutlineView,它从NSOutlineViewDataSource实现中加载数据。我希望所有项目在加载后都被展开,但我似乎找不到数据加载完成时触发的事件,这样我就可以发送[outlineView expandItem: nil expandChildren: YES]

我研究了NSOutlineViewDelegate协议,但我无法找到适合此调用的位置。这个问题的最佳解决方案是什么?

4个回答

10

通常我喜欢在表单内执行类似这样的操作——使用awakeFromNib或任何其他启动回调

dispatch_async(dispatch_get_main_queue(), ^{
    [self.outlineView expandItem:root expandChildren:YES];
});
这将在运行循环的当前周期末尾排队执行代码块,因此它将在所有初始化完成后执行。无需设置任何人为延迟。

不确定为什么会被踩。当我找不到其他解决方案时,这个对我很有用。谢谢! - Rotsiser Mho
最佳答案! :) 这个无论上下文都适用。 - Kappe

3
我想到的最佳解决方案是编写一个方法,在零延迟后展开NSOutlineView
- (void)windowDidLoad
{
    [super windowDidLoad];
    [self performSelector:@selector(expandSourceList) withObject:nil afterDelay:0.0];
}

- (IBAction)expandSourceList
{
    [mSourceListView expandItem:nil expandChildren:YES];
}

谢谢您建议使用windowDidLoad:这似乎是放置此类设置的好地方。但是,顺便说一下,我发现我不需要使用延迟,至少对于我正在尝试做的事情来说:我直接从windowDidLoad调用-expandItem:,到目前为止,这似乎有效。也许是由于以下原因之一:我在10.9.3上;我只展开某些行,因此我向-expandItem:提供特定项而不是nil...? - Ashley

2

我找到了答案。看起来实现委托方法-(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item就可以解决问题:


-(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    [outlineView expandItem:item];
}

请注意,这不是一个好的答案,它似乎在outlineview中的最后一项上出现问题,并且没有显示它们,任何帮助将不胜感激。 - matei

1

这是我通常处理这个问题的方法。我喜欢自己显示主窗口,而不是让它自动发生。这样我可以确保在向用户显示窗口之前设置好所有的界面项目。看起来你也可以这样做。所以首先,在接口生成器中取消窗口的“启动时可见”复选框。然后在我的应用程序代理类中,我使用这个方法,它是NSApplication的一个委托方法:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification

在这里,我设置我的界面项目,因为此时我知道一切都已经加载完毕。然后该方法的最后一行将是:[myWindow makeKeyAndOrderFront:self];。这样你就知道在用户看到窗口之前,你的窗口是完美的。所以我建议你在那里尝试你的方法。


谢谢,但这对我来说不是一个解决方案,因为outlineview位于当用户单击按钮时打开的面板中,并且数据似乎是在面板显示时加载的,而不是在应用程序启动时加载的。 - matei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接