objective-cmacoscocoanstableviewnsmenu

NSTableView to allow user to choose which columns to display


Anyone knows how to allow users to choose which columns of an NSTableView to be displayed by right clicking and then selecting? Just like iTunes does.


Solution

  • I have implemented this and the following should be usable without any subclassing.

    First implement an empty menu in IB and connect to the menu output of the Table Header View.

    This method (called from awakeFromNib) constructs the contents of the menu from the header (and includes a test to prevent users hiding a primary column)

    - (void)initViewHeaderMenu:(id)view {
        //create our contextual menu
        NSMenu *menu = [[view headerView] menu];
        //loop through columns, creating a menu item for each
        for (NSTableColumn *col in [view tableColumns]) {
            if ([[col identifier] isEqualToString:COLUMNID_NAME])
                continue;   // Cannot hide name column
            NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:[col.headerCell stringValue]
                                                        action:@selector(toggleColumn:)  keyEquivalent:@""];
            mi.target = self;
            mi.representedObject = col;
            [menu addItem:mi];
        }
        return;
    }
    

    This invokes the following to do the actual hiding/unhiding

    - (void)toggleColumn:(id)sender {
        NSTableColumn *col = [sender representedObject];
        [col setHidden:![col isHidden]];
    }
    

    You also need to set the delegate of the Menu and implement the following to set states:-

    #pragma mark NSMenu Delegate Methods
    -(void)menuWillOpen:(NSMenu *)menu {
        for (NSMenuItem *mi in menu.itemArray) {
            NSTableColumn *col = [mi representedObject];
            [mi setState:col.isHidden ? NSOffState : NSOnState];
        }
    }