NSSplitView
is notorious for being particularly fussy and troublesome; you sometimes have to go out of your way to make it behave properly. I knew my settings were being saved in User Defaults
- I could see them change correctly via the Terminal "Defaults read etc...
", but they weren't getting restored when the application reopened.
I solved it by manually reading the saved values and restoring the divider positions during awakeFromNib
.
Here's a Category on NSSplitView that politely asks it to please set its divider positions to their autosaved values:
@interface NSSplitView (PraxCategories)
- (void)restoreAutosavedPositions;
@end
@implementation NSSplitView (PraxCategories)
- (void)restoreAutosavedPositions {
// Yes, I know my Autosave Name; but I won't necessarily restore myself automatically.
NSString *key = [NSString stringWithFormat:@"NSSplitView Subview Frames %@", self.autosaveName];
NSArray *subviewFrames = [[NSUserDefaults standardUserDefaults] valueForKey:key];
// the last frame is skipped because I have one less divider than I have frames
for (NSInteger i=0; i < (subviewFrames.count - 1); i++ ) {
// this is the saved frame data - it's an NSString
NSString *frameString = subviewFrames[i];
NSArray *components = [frameString componentsSeparatedByString:@", "];
// only one component from the string is needed to set the position
CGFloat position;
// if I'm vertical the third component is the frame width
if (self.vertical) position = [components[2] floatValue];
// if I'm horizontal the fourth component is the frame height
else position = [components[3] floatValue];
[self setPosition:position ofDividerAtIndex:i];
}
}
@end
Then just call the method during awakeFromNib
for each NSSplitView
you wish to restore:
for (NSSplitView *splitView in @[thisSplitView, thatSplitView, anotherSplitView]) {
[splitView restoreAutosavedPositions];
}