如何在启动时设置 NSTreeController 的默认选择?
背景
我在我的 Cocoa 应用程序中构建了一个源列表(类似于 iTunes 等)。
我有一个带有 Value 的 NSOutlineView 绑定到arrangedObjects.name的列 NSTreeController 的关键路径。
NSTreeController 访问 Core 中的 JGSourceListNode 实体 数据存储。
我有三个子类 JGSourceListNode - JGProjectNode, JGGroupNode 和 JGFolderNode。
我已将 NSTreeController 上的 selectedIndexPaths 绑定到我的应用程序委托中名为 selectedIndexPaths 的 NSArray。
启动时,我搜索组节点,如果在核心数据存储中找不到它们,我将创建它们:
if ([allGroupNodes count] == 0) {
JGGroupNode *rootTrainingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootTrainingNode setNodeName:@"TRAIN"];
JGProjectNode *childUntrainedNode = [JGProjectNode insertInManagedObjectContext:context];
[childUntrainedNode setParent:rootTrainingNode];
[childUntrainedNode setNodeName:@"Untrained"];
JGGroupNode *rootBrowsingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootBrowsingNode setNodeName:@"BROWSE"];
JGFolderNode *childFolder = [JGFolderNode insertInManagedObjectContext:context];
[childFolder setNodeName:@"Folder"];
[childFolder setParent:rootBrowsingNode];
[context save:nil];
}
我想要的
当我启动应用程序时,我希望扩展两个顶级组并“未经训练”突出显示,如下所示:
我的窗口 http://synapticmishap.co.uk/Window.jpeg
问题
我将以下代码放在应用程序委托的 applicationDidFinishLaunching:
方法中:
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:0]];
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:2]];
NSIndexPath *rootIndexPath = [NSIndexPath indexPathWithIndex:0];
NSIndexPath *childIndexPath = [rootIndexPath indexPathByAddingIndex:0];
[self setSelectedIndexPaths:[NSArray arrayWithObject:childIndexPath]];
但是大纲视图似乎还没有准备好,所以这段代码什么也不做。
理想情况下,最终我想保存用户所做的最后选择并在重新启动时恢复它。
问题
我确信可以使用一些疯狂的 KVO 来观察 NSTreeController 或 NSOutlineView 何时被填充,然后展开项目并更改选择,但这感觉很笨拙,太像解决方法了。
我该如何优雅地做到这一点?
The Background
I've built a source list (similar to iTunes et al.) in my Cocoa app.
I've got an NSOutlineView, with Value
column bound to arrangedObjects.name
key path of an NSTreeController.The NSTreeController accesses
JGSourceListNode entities in a Core
Data store.I have three subclasses of
JGSourceListNode - JGProjectNode,
JGGroupNode and JGFolderNode.I have selectedIndexPaths on NSTreeController bound to an NSArray called selectedIndexPaths in my App Delegate.
On startup, I search for group nodes and if they're not found in the core data store I create them:
if ([allGroupNodes count] == 0) {
JGGroupNode *rootTrainingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootTrainingNode setNodeName:@"TRAIN"];
JGProjectNode *childUntrainedNode = [JGProjectNode insertInManagedObjectContext:context];
[childUntrainedNode setParent:rootTrainingNode];
[childUntrainedNode setNodeName:@"Untrained"];
JGGroupNode *rootBrowsingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootBrowsingNode setNodeName:@"BROWSE"];
JGFolderNode *childFolder = [JGFolderNode insertInManagedObjectContext:context];
[childFolder setNodeName:@"Folder"];
[childFolder setParent:rootBrowsingNode];
[context save:nil];
}
What I Want
When I start the app, I want both top level groups to be expanded and "Untrained" to be highlighted as shown:
My Window http://synapticmishap.co.uk/Window.jpeg
The Problem
I put the following code in the applicationDidFinishLaunching:
method of the app delegate:
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:0]];
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:2]];
NSIndexPath *rootIndexPath = [NSIndexPath indexPathWithIndex:0];
NSIndexPath *childIndexPath = [rootIndexPath indexPathByAddingIndex:0];
[self setSelectedIndexPaths:[NSArray arrayWithObject:childIndexPath]];
but the outline view seems to not have been prepared yet, so this code does nothing.
Ideally, eventually I want to save the last selection the user had made and restore this on a restart.
The Question
I'm sure it's possible using some crazy KVO to observe when the NSTreeController or NSOutlineView gets populated then expand the items and change the selection, but that feels clumsy and too much like a work around.
How would I do this elegantly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
优雅?这并不优雅,但我就是这样做的。我只是手动完成。在应用程序退出时,我将此值写入用户默认值:
然后在应用程序启动时,我在应用程序中运行此值并完成启动:
注意我只是使用延迟,因为我注意到与您相同的“大纲视图似乎尚未准备好” 。然后在该选择器中我使用它。
它有效,但我也欢迎更好(更优雅)的解决方案。
Elegantly? This isn't elegant but it's how I'm doing it. I just do it manually. At app quit I write this value to user defaults:
Then at app launch I run this in app did finish launching:
Notice I just use a delay because I noticed the same as you that "the outline view seems to not have been prepared yet". Then in that selector I use this.
It works but better (more elegant) solutions are welcome from me too.