【问题标题】:How do I set the default selection for NSTreeController at startup?如何在启动时为 NSTreeController 设置默认选择?
【发布时间】:2010-04-25 19:39:40
【问题描述】:

背景

我在我的 Cocoa 应用程序中构建了一个源列表(类似于 iTunes 等)。

  • 我有一个 NSOutlineView,带有 Value 绑定到排列对象名称的列 NSTreeController 的关键路径。

  • NSTreeController 访问 核心中的 JGSourceListNode 实体 数据存储。

  • 我有三个子类 JGSourceListNode - JGProjectNode, JGGroupNode 和 JGFolderNode。

  • 我已将 NSTreeController 上的 selectedIndexPaths 绑定到我的 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 何时被填充,然后展开项目并更改选择,但这感觉很笨拙,太像解决方法了。

我将如何优雅地做到这一点?

【问题讨论】:

    标签: cocoa startup cocoa-bindings nsoutlineview nstreecontroller


    【解决方案1】:

    优雅吗?这并不优雅,但我就是这样做的。我只是手动完成。在应用退出时,我将此值写入用户默认值:

    lastSelectedRow = [outlineView selectedRow]
    

    然后在应用程序启动时,我在应用程序中运行它确实完成了启动:

    [self performSelector:@selector(selectLastNoteOrCreateDefaultNote) withObject:nil afterDelay:1];
    

    注意我只是使用延迟,因为我和你一样注意到“大纲视图似乎还没有准备好”。然后在那个选择器中我使用它。

    [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:lastSelectedRow] byExtendingSelection:NO];
    

    它有效,但我也欢迎更好(更优雅)的解决方案。

    【讨论】:

    • 您可能应该将延迟设置为0,这将在事件循环的下一次迭代中发送消息,而不会出现可见的“延迟”。
    • 嘿,Rob,这确实有效。我很惊讶,但我想它只需要等待你提到的下一个事件循环......当然0延迟更好/更快。谢谢。
    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2020-08-07
    • 2014-04-15
    • 2019-04-18
    相关资源
    最近更新 更多