How to update NSTableView without using -reloadData?

13,756

Solution 1

Have a look at reloadDataForRowIndexes:columnIndexes: method. To update a single cell the following should work:

[yourTable reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:row]  
                     columnIndexes:[NSIndexSet indexSetWithIndex:column]];

Solution 2

This is a fundamental difference between the way views typically work in Cocoa and how they work in some other frameworks. NSTableView does expose a -reloadDataForRowIndexes:columnIndexes: API, as Vladimir points out, but you'll notice the absence of a "withObject:" parameter.

This is because Cocoa views and controls are not designed to also act as data containers. Rather, they're for presentation of and interaction with data that is managed by some other model object, usually through an intermediate controller of some sort.

Given a table view, for example, if your model has informed your controller that some particular data has changed, the controller can invalidate the displayed portion of the table that maps to that value - if there even is a displayed portion of the table. The next time it draws itself, the table will ask its data source (the controller) for the values to present for the area it needs to redraw.

Thus despite a superficial similarity in user interaction, you'll probably want to reconsider how you write the code to implement your user interface. You'll wind up with much more factored Model-View-Controller style code in the end; the price is that you'll need to actually represent your model more thoroughly than you might have had to in frameworks that didn't require such a separation of concerns.

Solution 3

A full example of using reloadDataForRowIndexes to update all rows but only a single column:

int col = 2 ;
[self.myTable reloadDataForRowIndexes:
    [NSIndexSet indexSetWithIndexesInRange:
        NSMakeRange(0,self.myTable.numberOfRows)] 
    columnIndexes:
        [NSIndexSet indexSetWithIndex:col]
];

Or all columns for a single row:

int row = 2 ;
[self.myTable reloadDataForRowIndexes:
    [NSIndexSet indexSetWithIndex:row]
columnIndexes:
    [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.myTable.numberOfColumns)]
];
Share:
13,756
Omayr
Author by

Omayr

For last couple of years, I have developed a wide range of websites using HMTL, CSS, PHP, JavaScript, Jquery, Wordpress, Joomla, Drupal and MySQL . My core competency lies in complete end-end management of a new website development project, and I am seeking opportunities to build websites from the ground up for you or your business. I am working along with my team and we have a sound experience in developing small, medium and big scale websites. We don't work as ordinary order taker rather offer more than that. In my career I have worked with both technical and non-technical clients. The problem with non-technical clients is that they cannot turn what they are looking for into concrete functional requirements. I have sound expertise in converting the needs of non-technical clients into functional requirement so that while we are in development phase there is no conflict between the client's understanding and the the development team's understanding .

Updated on June 09, 2022

Comments

  • Omayr
    Omayr almost 2 years

    I am new to the Mac. I am trying to update a particular cell in NSTableView without using -reloadData, as -reloadData updates the whole table. I have tried everything but all was in vain. I am trying to do something similar to what we used to do in CListCtrl in MFC or in .NET.

  • Omayr
    Omayr over 13 years
    I want to do this because of efficiency. Like I need to update 8-10 cells per second it this case I dont want the whole table to be updated over and again !
  • Michael Teper
    Michael Teper over 9 years
  • Matt
    Matt over 8 years
    While this is the correct solution it should be mentioned that reloadData() also just re-renders the currently visible cells and not the entire table.
  • TheNextman
    TheNextman almost 7 years
    In your second example, reloadDataForRowIndexes:columnIndexes: can't take an NSRange, so you need to do something like: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, _tableView.numberOfColumns)]