Search code examples
objective-ccocoanstableviewnstableviewcell

Change NSTableView cell value While Editing


I want to change the value being displayed in a NSTableView Cell while editing it. My requirement is the following: Initially I entered a cell value of 234.5678978 and after editing the value is being rounded up to 0 decimal precision(that means 235). My requirement is that when I could click that cell, it should show me value unto certain decimal precision say up 5 precision, in this case 234.56790). How can I achieve this functionality. I tried to capture the action of double click editing the cell of NSTableView:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidEnd:)
                                                 name:NSControlTextDidEndEditingNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidBegin:)
                                                 name:NSControlTextDidBeginEditingNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidChange:)
                                                 name:NSControlTextDidChangeNotification object:nil];

- (void)editingDidEnd:(NSNotification *)notification
{
    NSLog(@"text editing fisnished");
}

- (void)editingDidBegin:(NSNotification *)notification
{
    NSLog(@"text is being edited");
}
- (void)editingDidChange:(NSNotification *)notification
{
    NSLog(@"text was being changed");
}

But only editingDidEnd was called on tab out and the other two methods were never called.


Solution

  • I added a custom formatter for the edited cell in willDisplayCell delegate of NSTableView

    - (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
        if(tableView == self.tableView)
        {
            if(![[tableColumn identifier]isEqualToString:@"name"]){
                [cell setFormatter:nil];
    
                if (row == [tableView editedRow] && [[tableView tableColumns] indexOfObject:tableColumn] == [tableView editedColumn]) // the cell is getting edited
                {
                    [(NSTextFieldCell*)cell setTextColor:[NSColor redColor]];
                   NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
                    [nf setMaximumFractionDigits:5]; // Setting the precision value upto 5 decimal places
                    [nf setMinimumFractionDigits:0];
                    [cell setFormatter:nf];
                }
                else{
                    [(NSTextFieldCell*)cell setTextColor:[NSColor blackColor]];
                    //[cell setFormatter:nil];
                    NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
                    [nf setMaximumFractionDigits:2]; // setting decimal value upto 2 decimal places
                    [nf setMinimumFractionDigits:0];
                    [cell setFormatter:nf];
                }
            }
    
        }
    }
    

    So, when a cell is edited, it will set the precision to 5 decimal places and in all other cases it will set cell formatter to 2 decimal places.