Search code examples
objective-ccocoacore-datasubclassnsarraycontroller

How can I subclass NSArrayController to select a text field on add:


This is simple I am sure, but I am still very much learning.

I have an NSTableView that is connected to an array controller to display coredata objects. The table is uneditable. When a single record is selected, I have a subview set to be made visible that holds the value of the selection.

I'm trying to make it so that when I press the + button connected to add: on my array controller, a new entry will be made and the focus will jump to the item description text field in the subview so that a user could immediatily begin typing without having to select the new arrangedObject row and then the textfield when the subview appears.

any ideas?

I would post screenshots but I haven't been a user on here long enough.


Solution

  • Big Nerd Ranch's Cocoa book (4th edition) has an example of this in Chapter 9. Instead of using NSArrayController's -add: method for the + button, they use a custom method to create the object, insert it into the array, deal with in-progress edits and undo manager groupings, and finally select the desired field for editing. Here's the excerpt:

    - (IBAction)createEmployee:(id)sender
    {
    NSWindow *w = [tableView window];
    // Try to end any editing that is taking place
    BOOL editingEnded = [w makeFirstResponder:w];
    if (!editingEnded) {
        NSLog(@"Unable to end editing");
        return; }
    NSUndoManager *undo = [self undoManager];
    // Has an edit occurred already in this event?
    if ([undo groupingLevel] > 0) {
        // Close the last group
        [undo endUndoGrouping];
        // Open a new group
        [undo beginUndoGrouping];
    }
    // Create the object
    Person *p = [employeeController newObject];
    // Add it to the content array of ’employeeController’
    [employeeController addObject:p];
    // Re-sort (in case the user has sorted a column)
    [employeeController rearrangeObjects];
    // Get the sorted array
    NSArray *a = [employeeController arrangedObjects];
    // Find the object just added
    NSUInteger row = [a indexOfObjectIdenticalTo:p];
    NSLog(@"starting edit of %@ in row %lu", p, row);
    // Begin the edit in the first column
    [tableView editColumn:0
                      row:row
                withEvent:nil
                   select:YES];
    }
    

    Full implementation is at https://github.com/preble/Cocoa4eSolutions.