cocoanstableviewnswindowrestoration

Restoring the selection in an NSTableView (NSWindowRestoration)


I'm working on window restoration in a non-document-based Cocoa app. The app has a Mail.app-like interface. Each window represents an account; a sidebar in that window lists conversations in that account, and a main area lists messages in the selected conversation.

Each of these lists is a view-based NSTableView. The conversation list is bound to an NSArrayController whose contentSet is bound to the window controller's account property; the message list is bound to a second NSArrayController, whose contentSet is bound to the first NSArrayController's selection.

I've gotten my window restoration work to the point where it re-opens all the windows and re-associates them with the account objects, but I don't know how to restore the selections of the table views. This doesn't seem to happen automatically—when the window is restored, an object is selected, but it's not the one that was previously selected. What's going on here? What will be the easiest approach to saving and restoring the selection?


Solution

  • As you realized, NSTableView doesn't auto save the selection.

    The easiest way is to bind your NSTableView's selectionIndexes to your Array Controller's selectionIndexes, and save/retrieve values from NSUserDefaults. Then you can bind the array controller's selectionIndexes to the Shared User Defaults Controller (with Controller Key values and you can name your Model Key Path anything). Because NSIndexSet needs to be archived/unarchived to be stored, use the NSKeyedUnarchiveFromData value transformer. That, in itself, should work.


    If you had trouble like I did with the selection indexes resetting because the table view wasn't immediately repopulated (I doubt you'd have these problems, because you're populating with bindings), you can save defaults manually.

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setValue:[NSKeyedArchiver archivedDataWithRootObject:self.arrayController.selectionIndexes] valueForKey:vvLastSavedSelectionIndex];
    

    And retrieve them:

    NSIndexSet *selectionIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] valueForKey:vvLastSavedSelectionIndex]];
    [self.arrayController setSelectionIndexes:selectionIndexes];