objective-cmacoscocoansoutlineviewdisclosure

Cocoa NSOutlineView deselect previous selection


I have a NSOutlineView, some of those have children some don't. I would like to deselect, or close the previous selection when a selection is made on other cell.

I hope I can be explanatory with these screen shots.

enter image description here

Here we have Two Parent Folders, Folder 1 and Folder 2. I want to deselect Folder 1 on selecting the disclosure triangle of Folder 2.

enter image description here

Something like this, using the

-(BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item;
-(BOOL)outlineView:(NSOutlineView *)outlineView shouldCollapseItem:(id)item;

I haven't found a way out.

Thanks


Solution

  • Implement this delegate and use something similar :

    - (void)outlineViewItemDidExpand:(NSNotification *)notification{
        for (id parent in list) {
            if ([notification.userInfo objectForKey:@"NSObject"] == parent) {
                continue;
            }
            [notification.object collapseItem:parent];
        }
    }
    

    Here parent is the top level item array, as in your example Folder1 and Folder2.

    EDIT:

    Appdelegate.h

    @interface AppDelegate : NSObject <NSApplicationDelegate>
    
    @property (assign) IBOutlet NSWindow *window;
    
    @property(strong) NSDictionary *firstParent;
    @property(strong)  NSDictionary *secondParent;
    @property(strong) NSArray *list;
    
    @end
    

    Appdelegate.m

    @implementation AppDelegate
    
    @synthesize firstParent;
    @synthesize secondParent;
    @synthesize list;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        // Insert code here to initialize your application
    }
    
    - (id)init {
        self = [super init];
        if (self) {
    
            firstParent = [NSDictionary dictionaryWithObjectsAndKeys:@"A",@"parent",
                           [NSArray arrayWithObjects:@"Apple",@"Aeroplane", nil],@"children", nil];
    
            secondParent = [NSDictionary dictionaryWithObjectsAndKeys:@"B",@"parent",
                            [NSArray arrayWithObjects:@"Ball",@"Baloon", nil],@"children", nil];
            list = [NSArray arrayWithObjects:firstParent,secondParent, nil];
    
        }
        return self;
    }
    
    
    - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item{
        if ([item isKindOfClass:[NSDictionary class]]) {
            return YES;
        }
        else {
            return NO;
        }
    }
    
    - (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item{
    
        if (item == nil) { //item is nil when the outline view wants to inquire for root level items
            return [list count];
        }
    
        if ([item isKindOfClass:[NSDictionary class]]) {
            return [[item objectForKey:@"children"] count];
        }
    
        return 0;
    }
    
    - (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item{
    
        if (item == nil) { //item is nil when the outline view wants to inquire for root level items
            return [list objectAtIndex:index];
        }
    
        if ([item isKindOfClass:[NSDictionary class]]) {
            return [[item objectForKey:@"children"] objectAtIndex:index];
        }
    
        return nil;
    }
    
    - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item
    {
    
        if ([[theColumn identifier] isEqualToString:@"children"]) {
            if ([item isKindOfClass:[NSDictionary class]]) {
                return [NSString stringWithFormat:@"%ld kids",[[item objectForKey:@"children"] count]];
            }
            return item;
        }
        else{
            if ([item isKindOfClass:[NSDictionary class]]) {
                return [item objectForKey:@"parent"];
            }
        }
    
        return nil;
    }
    

    With one more method written on top.

    And set the delegate of NSOutlineView to AppDelegate in IB.