背景
我在我的Cocoa应用程序中构建了一个源列表(类似于iTunes等)。
我有一个带有Value的NSOutlineView
列绑定到arrangeObjects.name
NSTreeController访问 核心中的JGSourceListNode实体 数据存储。
我有三个子类 JGSourceListNode - JGProjectNode, JGGroupNode和JGFolderNode。
我在NSTreeController上选择了绑定到我的App Delegate中名为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];
}
我想要什么
当我启动应用程序时,我希望两个顶级组都得到扩展,并且“未经训练”将突出显示如下所示:
My Window http://synapticmishap.co.uk/Window.jpeg
问题
我将以下代码放在app delegate的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何时被填充,然后展开项目并更改选择,但这感觉很笨拙,太像工作了。
我如何优雅地做到这一点?
答案 0 :(得分:1)
优雅?这不是优雅,但它是我如何做到这一点。我只是手动完成。在app退出时,我将此值写入用户默认值:
lastSelectedRow = [outlineView selectedRow]
然后在应用程序启动时,我在应用程序中运行此操作完成启动:
[self performSelector:@selector(selectLastNoteOrCreateDefaultNote) withObject:nil afterDelay:1];
注意我只是使用延迟,因为我注意到了“大纲视图似乎还没有准备好”。然后在那个选择器中我使用它。
[outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:lastSelectedRow] byExtendingSelection:NO];
它有效,但我也欢迎更好(更优雅)的解决方案。