How can I subclass NSArrayController to select a t

2019-09-07 07:13发布

问题:

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.

回答1:

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.



回答2:

Yep, it's simple:

Don't use NSArrayController.

The class is only suitable when you do not need any control at all over how things work. If you need control, you should create your own controller object that is the data source and delegate of the table view, and has an NSFetchedResultsController to access core data.

Personally I've only ever used NSArrayController as a prototype. Once I start getting serious about the app I always throw it out, and put a custom written controller in its place.