How do I set the default selection for NSTreeController at startup?

Posted by John Gallagher on Stack Overflow See other posts from Stack Overflow or by John Gallagher
Published on 2010-04-25T19:39:40Z Indexed on 2010/04/25 19:43 UTC
Read the original article Hit count: 400

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

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?

© Stack Overflow or respective owner

Related posts about nsoutlineview

Related posts about nstreecontroller