0
votes

I have an app that needs to present a lot of data by group. I had put a group selection menu in the table's corner view to allow the user to choose the group to view.

This table's columns has identifiers fld# 0..n, and an associated controller to fetch data. In the target class, it would - using an IBOutlet binding to the view controller retrieve the group selection and use that to select via switch which value to show.

All was dandy, until I needed to support multiple view/window instances. So I was thinking I would at run-time, alter the ? in the tablecolumn(s) and its bindings. To date I'd only ever done such via IB so this is my first foray into the innards and getting stuck.

My corner view action menu ( what user invokes ):

- (NSMenu *)menuForEvent:(NSEvent *)event
{
    NSMenu * menu = [[[NSMenu alloc] init] autorelease];
    SEL action = @selector(cornerAction:);
    NSMenuItem * item = nil;
    int type = 0;

    //  We auto enable items as views present them
    [menu setAutoenablesItems:YES];

    //  TableView level column customizations
    for (NSString * title in titles)
    {
        BOOL state = dataView.data == type;

        item = [[NSMenuItem alloc] initWithTitle:title
                                          action:action
                                   keyEquivalent:@""];
        [item setRepresentedObject:dataView];
        [item setState:state];
        [item setEnabled:YES];
        [item setTag:type++];
        [item setTarget:dataView];
        [item setAction:action];
        [menu addItem:item];
        [item release];
    }
    return menu;
}

and then acted upon - but fails as I need to figure out how to update the bindings:

- (IBAction)cornerAction:(id)sender
{
    //  Configure which type of data to show, then columns' identifier and sort 
    self.data = (self == sender ? 0 : [sender tag]);

    [super cornerAction:sender];

    for (NSUInteger itm=0; itm<self.fieldCount; itm++)
    {
        NSString * fld = [NSString stringWithFormat:@"fld%@%d", titles[data], itm];
        NSString * key = [NSString stringWithFormat:@"srt%@%d", titles[data], itm];
        NSSortDescriptor * srt = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES];

        [cols[itm] setIdentifier:fld];
        [cols[itm] setSortDescriptorPrototype:srt];

        [cols[itm] bind:<#(nonnull NSString *)#>
               toObject:<#(nonnull id)#>
            withKeyPath:<#(nonnull NSString *)#>
                options:<#(nullable NSDictionary<NSString *,id> *)#>]
    }

    [self reloadArray:YES];
}

cols[] is an array of table columns so the last line is a starting point to updating the bindings for the column to the controller (a tree controller) to the right data. I'd updated the class to remove the fld# placesholder columns and created all variants of the fld# and srt# ivars; these basically return the underlying ivar. Lastly, all access is read only.

I was thinking all that I need to do now is update the binding. I also feel perhaps the column changes to identifier and sort descriptor aren't necessary?

Anyway I'm trying to avoid plan-B which is to resort to tabs, instantiating the tableview per group - yuck, or perhaps there's a better way altogether ?

UPDATE: presuming I continue along plan-A shouldn't this work: presume column identifier for cols[0] is fld0

        [cols[itm] bind: @"value"
               toObject: treeController
            withKeyPath: [NSString stringWithFormat:@"arrangedObjects.%@",fld]
                options: nil]
1
Is the table view view based or cell based?Willeke
Usually, if you have a table bound to a controller, and you want to change what is displayed in the table, you change the controller's content... you don't tear down the view's bindings. And if you want to have the a different data set binded and displayed differently, you might want to approach it by dynamically displaying a different view, not the same view with reconstructed bindings.stevesliva
So, yeah, it's kinda re-scrambling the eggs into an omelet, so use a tabbed view (tab less) of several tabs I think is the way to go.slashlos
it's a cell based view.slashlos

1 Answers

0
votes

Due to implicit caching / object cloning the simplest solution was to instantiate the table view. The UI was kept consistent so no user visible changes which I needed, and is a model going forward for other similar requirements - how to view vast amounts of data via a single lens / table view metaphor.