How to create an action from selecting a row from an NSTableView

Coderama picture Coderama · Feb 4, 2012 · Viewed 16.2k times · Source

When I select a row from NSTableView, it is not running the code from tableViewSelectionDidChange method. I had put break points in this method and it is not even going into the method.

Any ideas? Am I missing something in my initialiser?

PersonController.h

#import <Foundation/Foundation.h>

@interface Person : NSObject {
  IBOutlet NSTableView *personsTable;
  NSMutableArray *personsList;
  NSMutableArray *personCollection;

  IBOutlet NSTextField *selectedPersonName;
  IBOutlet NSTextField *selectedPersonGender;
@private

}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification;

@end

PersonController.m

#import "PersonController.h"
#import "Person.h"


@implementation PersonController

- (id)init
{
    self = [super init];
    if (self) {
        personsList = [[NSMutableArray alloc] init];
        Person *person = [[Person alloc] init];

        // Create person 1
        person.name = @"Bob";
        person.gender = @"male";

        // Append to array
        [personsList addObject:person];
        [person release];

        // Create person 2
        person = [[Person alloc] init];
        person.name = @"Fred";
        person.gender = @"Unknown";

        // Append to array
        [personsList addObject:person];
        [person release];

        [personsTable reloadData];
    }

    return self;
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    return [personsList count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    Person *person = [personsList objectAtIndex:row];
    NSString *identifier = [tableColumn identifier];

    return [person valueForKey:identifier];
}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
    NSInteger selectedRow = [personsTable selectedRow];
    if (selectedRow == -1)
    {
        // these should be localized, but use string constants here for clarity
        [selectedPersonName setStringValue:@"No selection"];
        [selectedPersonGender setStringValue:@"No selection"];
    }
    else
    {
        Person *selectedPerson = [personCollection objectAtIndex:selectedRow];

        [selectedPersonName setStringValue:[selectedPerson name]];
        [selectedPersonGender setStringValue:[selectedPerson gender]];
    }
}

- (void)dealloc
{
    [super dealloc];
}

@end

Answer

Coderama picture Coderama · Feb 7, 2012

So the issue here was that I was trying to use the tableViewSelectionChange to trigger an event when a row in the NSTableColumn was clicked. As I couldn't get this working I took another approach which was to create an IBAction and link this to the NSTableView and I have found this to work well.

In order to do this, I did the following:

  1. Delete - (void)tableViewSelectionDidChange
  2. Create IBAction
  3. In the XIB file, create a Received Actions link between the IBAction and the NSTableView, in NSTableView connection inspector under "sent action" have "selector" action" connect this "selector" with that IBAction you want to trigger.

This is the IBAction in PersonController.m

- (IBAction)columnChangeSelected:(id)sender
{
    NSInteger selectedRow = [personsTable selectedRow];

    if (selectedRow != -1) {
        NSLog(@"Do something with selectedRow!");
    }
    else {
        // No row was selected
    }
}