Selecting and Editing New Object in NSTableView

I am trying to select and change the name property of a newly added object.

On OSX, I have an array controller that displays its contents as a table. I have table column values ​​linked (using bindings) via AC properties. Also, I am setting the table view content and selectIndexes bindings to point to AC.

My subclass AC has an IBOutlet for the table view (called tableView) and contains managed objects from the data model.

In my AC, I am overriding the add: method.

- (void)add:(id)sender {
    [super add:sender];
    [[self managedObjectContext] processPendingChanges]; // no effect
    [tableView reloadData]; // no effect
    [tableView scrollRowToVisible:[[self arrangedObjects] count]-1];


The newly added object appears in the table view in the selected state (I have an AC configured in IB to select newly inserted objects). But the table view scrolls to the second last row, putting the new row directly from the visible view.

When I try this,

[tableView scrollRowToVisible:[tableView selectedRow]];


or that,

[tableView scrollRowToVisible:[self selectionIndex]];


it gets worse: selectionIndex doesn't seem to update correctly.

- (void)add:(id)sender {
    [super add:sender];
    NSLog(@"selectionIndex = %lu", [self selectionIndex]);
    NSLog(@"number of objects in AC = %lu", [[self arrangedObjects] count]);


The selectIndex login shows that it always shows the previous selection index. The logging of the number of objects in AC is always too low.

Am I trying to manipulate the table view too early? Any ideas which method is best for overriding?

About the editing part ..

The following statement interferes with the above scrollRowToVisible method: since the last argument seems to select the row as well.

[tableView editColumn:0 row:0 withEvent:nil select:YES];


In any case, the specified field (for testing purposes, the first row of the table) seems to go into edit mode just flickering a moment, but then finishes editing immediately.

Any help would be greatly appreciated.


source to share

2 answers

In one of the solutions, I came up with:

- (void)rearrangeObjects {
    [super rearrangeObjects];
    [tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:YES];


The last argument select:YES

does not scroll the table to a row or select a row. The next line also scrolls the table view.

[tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:NO];



selects text in the text box that is being edited.

However, I am wondering if I will do it right. This solution requires each array controller to have an output to a table view that displays its data. This seems overkill since the table view (and its columns) is already bound to AC.

Trying to implement the MVC design pattern, shouldn't the responsibility for editing the cell be delegated to the table view?



The problem is that the array controller doesn't add a new object immediately. The documentation for - [NSArrayController add:] says:

Starting with Mac OS X v10.4, the result of this method is deferred until the next iteration of runloop so that the error reporting mechanism (see Error Responders and Error Recovery) can provide sheet-like feedback.

I don't know what an elegant way to get around this. You can try to work around the method add:

by adding the object directly NSMutableArray

to which the array controller is bound to. Alternatively, you can try using it performSelector:withObject:afterDelay:

with a slight delay, for example 0.1 seconds, after which the object should be added.



All Articles