Question

I'm dynamically adding rows to an NSTableView. When I issue [table reloadData] I can see the scroll view move and if I move it by hand I can see the new value on the table. But how can I scroll it automatically?

Was it helpful?

Solution

NSInteger numberOfRows = [tableView numberOfRows];

if (numberOfRows > 0)
    [tableView scrollRowToVisible:numberOfRows - 1];

Assuming you're adding rows to the end of the table.

(The reason I ask the table view for the number of rows instead of the data source is that this number is guaranteed to be the number of rows it knows about and can scroll to.)

OTHER TIPS

Use something like this:

 [table scrollRowToVisible:indexOfNewRow];

I solved it as shown below, using the didAddRowView to work properly: Obviously, if I add a new record, the tableview needs to create a new row view.

- (void)tableView:(NSTableView *)tableView  didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
// it sends notification from all tableviews.
// I am only interested in the dictionary...

if (tableView == dictTableView){
    if ( row == [dictTableView numberOfRows]-1){
        [dictTableView scrollRowToVisible:row];
    }
}

}

But also, in my IBAction I added 2 lines after performing the add statement to the controller

- (IBAction)addNewDictItem:(id)sender {
NSInteger row=[[theDictArrayController arrangedObjects]count];

[theDictArrayController add:sender];
[dictTableView noteNumberOfRowsChanged];
[dictTableView scrollRowToVisible:row-1];

}

A improved solution to my previous one is shown below. Catching the "didAddRow" event is probably still too early, so that the new row (to scroll to...) is not available yet.

First, create your own "add" action , keep a flag as reminder and call the controller's add action.

-(IBAction)addNewDictItem:(id)sender {
   [theDictArrayController add:sender];
   dictElementAdded=TRUE;
 }

Now, when the controller adds an object, it selects this object automatically. Just "hop on" this event by catching the notification from the tableview. Nice thing about it: lines and views are created before, and the new row is ready to be selected.

-(void)tableViewSelectionDidChange:(NSNotification *)aNotification {
NSTableView * tableView=[aNotification object];

if (dictElementAdded && tableView == dictTableView  ){
    NSInteger   row= [[tableView selectedRowIndexes ] firstIndex ];        
        [dictTableView scrollRowToVisible:row];
        dictElementAdded = FALSE;
 }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top