Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autosave Expanded Items of NSOutlineView doesn't work

I am trying to use the "Autosave Expanded Items" feature. When I expand a group with its children and restart the application all children are collapsed again and I don't know why they won't stay expanded. I'm using core data to store my source list items.

This is what I have done/set so far:

  • Checked "Autosave Expanded Items" in NSOutlineView (Source List)
  • Set a name for "Autosave"
  • dataSource and delegate outlets assigned to my controller

This is my implementation for outlineView:persistentObjectForItem and outlineView:itemForPersistentObject.

- (id)outlineView:(NSOutlineView *)anOutlineView itemForPersistentObject:(id)object
{
    NSURL *objectURI = [[NSURL alloc] initWithString:(NSString *)object];  
    NSManagedObjectID *mObjectID = [_persistentStoreCoordinator managedObjectIDForURIRepresentation:objectURI]; 
    NSManagedObject *item = [_managedObjectContext existingObjectWithID:mObjectID error:nil];
    return item;  
}

- (id)outlineView:(NSOutlineView *)anOutlineView persistentObjectForItem:(id)item
{
    NSManagedObject *object = [item representedObject];
    NSManagedObjectID *objectID = [object objectID];
    return [[objectID URIRepresentation] absoluteString];
}

Any ideas? Thanks.

EDIT: I have a clue! The problem is maybe that the tree controller has not prepared its content on time. The methods applicationDidFinishLaunching, outlineView:persistentObjectForItem etc. are being be executed before the data has loaded or rather the NSOutlineView hasn't finished initializing yet. Any ideas how to solve this?

like image 830
krema Avatar asked Sep 11 '14 14:09

krema


2 Answers

I've had the problem that my implementation of -outlineView:itemForPersistentObject: was not called at all. It turns out that this method is called when either "autosaveExpandedItems" or "autosaveName" is set. My solution was to set both properties in Code and NOT in InterfaceBuilder. When i set the properties after the delegate is assigned, the method gets called.

like image 103
Karsten Avatar answered Oct 17 '22 09:10

Karsten


I got this to work - you need to return the corresponding tree node instead of "just" its represented object.

In itemForPersistentObject:, instead of return item; you need return [self itemForObject:item inNodes:[_treeController.arrangedObjects childNodes]];

with

- (id)itemForObject:(id)object inNodes:(NSArray *)nodes {
    for (NSTreeNode *node in nodes) {
        if ([node representedObject] == object)
            return node;

        id item = [self itemForObject:object inNodes:node.childNodes];
        if (item)
            return item;
    }

    return nil;
}

where _treeController is the NSTreeController instance that you use to populate the outline view.

like image 30
MrMage Avatar answered Oct 17 '22 08:10

MrMage