Reputation: 1505
When using XCode and you open a "plist" file you get the contents in a nice outline view.
In my project CoreDataUtility I would like to do something very similar. In core data a developer can store NSDictionary and NSArray as a transformable object. I would like to be able to present those object in a nice tree view instead of just dumping the description to a NSTextView.
I'm sure I can start coding it and get it to work but first I wanted to check if anyone knows how to get NSTreeView to do this intrinsically or if anyone has sample code that already does something similar?
Thanks for any help you might be able to offer.
Upvotes: 1
Views: 366
Reputation: 12095
You cannot use nested NSDictionary
objects directory with an NSTreeController
because a dict's children wouldn't be of the correct form, as you'd always need same-named keyPaths for the value you want to show in the NSOutlineView
's columns.
However, you can easily convert the nested NSDictionary
objects into a slightly different representation that meets this requirement.
Consider you have an outlineview with two columns. You'd bind the first column's Value to the Tree Controller's arrangedObjects.col1
and the second to arrangedObjects.col2
.
Then here's the code for creating a suitable NSDictionary
:
- (NSDictionary*) makeNodeFrom:(NSObject*)value withName:(NSString*)name {
NSMutableDictionary *result = NSMutableDictionary.dictionary; // has keys: name, value, children, isLeaf, count
result[@"col1"] = name;
if ([value isKindOfClass:NSDictionary.class]) {
NSMutableArray *children = NSMutableArray.array;
[(NSDictionary*)value enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSObject *obj, BOOL *stop) {
[children addObject:[self makeNodeFrom:obj withName:key]];
}];
result[@"children"] = children;
result[@"count"] = @(children.count);
} else {
result[@"isLeaf"] = @YES;
result[@"col2"] = value;
}
return result;
}
// return the model from a generic dictionary:
- (NSDictionary)myModel {
NSDictionary *sampleDict = @{
@"key1": @"value1,
@"node": @{
@"key2": @"value2"
}
};
return [self makeNodeFrom:sampleDict withName:@"root"];
}
In the Tree Controller, bind its Content Array to myModel
, and set its keyPath properties as follows:
children
count
isLeaf
Upvotes: 0