Adding columns to view-based NSTableView programmatically - cocoa

I currently have a cell-based NSTableView where I need to add columns and bind them to my model. The text size for the columns is System-Small and everything works great because I can programmatically set the properties of the dataCell when I create the column.
With a view-based table and no dataCell, how can I make sure during the column creation that the text cell is the right size, etc? There does not seem to be a way to store a template column in the nib and load it multiple times (each time changing the identifier), before adding it to the table.
In switching to a view-based NSTableView, I understand that I can't bind a whole column on creation like I can with cell-based tables, but instead have to do it during:
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
I can bind like this, but just need a way to pre-configure the appearance and layout of a column as I can't figure out how to even find the views within a new column as they don't have any identifiers like they would if they came from some sort of template.

Related

View-based NSTableView view controllers

I'm not sure if I am doing things right but this is my problem:
I have a view-based NSTableView using bindings to an arraycontroller.
I need to do some custom drawing on each row, depending the represented object as well as capture click in certain areas so for this I would need to have a controller for each row and set outlets for the sub-views in my custom cell view, but I don't understand how I can achieve this.
If I just add an object to the nib and make the connections to it, then I cannot tell which of the views is being drawn (or has been clicked).
You have to implement the delegate methods :
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
It's used by the table view to get a view for a give cell (column, row).
Then by using "makeViewWithIdentifier:owner:", you can get the a reusable cell with a given identifier and a given owner (view controller).
The simplest way is to design your cells in Interface Builder, and set a different identifier for each one. Then the method "makeViewWithIdentifier:owner" will automatically create a view for you for the given identifier.
I just found someone asked a similar question and the answer to it also satisfies my needs, so for anyone ending up here, this is what I did:
I set my NSTableCellView controller as the delegate of the NSTableView.
In my NSTableCellView subclass I implement the needed methods (drawRect:, mouseUp: and so forth) and call the respective methods in the controller.
To access the controller I get the NSTableView and then its delegate like this:
NSTableView *tableView = (NSTableView*)myView.superview.superview.superview;
MyControllerClass *controller = (MyControllerClass*)tableView.delegate;
[controller view:myView drawRect:dirtyRect]
On the controller, to tell which view is sending an event, I use their identifiers.

View-based table view with NSColorWell

I have a an NSMutableArray set up with objects that have a color, a bool value, and a name. I would like to have the array displayed in a table view with a color well depicting the object's color value, a check box for its bool value and then the name in the third column. I haven't had trouble setting up a table view with just a check box and name, however I am running in to some issues trying to get a color well to show up in the table.
I'm fairly certain I need to use a view-based table view instead of cell based table view, and that is where I am running into trouble. Am I supposed to use bindings to set up the table? If so how might I do that?
If not, what would be the correct way to set up a view-based table view?
I've tried using
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
and
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
However this doesn't seem to work. I've looked into using an NSArrayController, but I don't think that's what I need to implement this.
Any ideas?
Thanks!
I found an answer that worked.
I used a custom cell called LVColorWellCell (http://ringce.com/code/Cocoa/lvcolorwellcell) to implement a color well cell in a cell-based table view and it works great!

Cocoa - View-Based NSTableView, using one cell in multiple tables

I've got a problem. [for which the only example I can find was shown during one of the WWDC 2011 presentations ("Maximising Productivity in Xcode 4"), but there is no source available (it was an app called Birdathon). Everything else I come up with is for iOS, and doesn't translate across.]
Basically, I have some view-based NSTableViews, and currently lay out the image / text fields within my NSTableCellView directly in the column. I've got a subclass of NSTableCellView which gives me the outlets to assign values to each of the text fields I use within that cell. The DataSource and Delegate are implemented and working fine - the TableView with my custom NSTableViewCell works fine.
My problem is I'd like to use the same cell in multiple different tables. Rather than have to recreate the same layout each time, I feel I should be able to draw the NSTableCellView just once in IB. [- and indeed, the Birdathon example I mentioned seemed to show the NSTableCellView being laid out in it's own NIB.]
I've found the answer for iOS in many places, here for example: How do you load custom UITableViewCells from Xib files?
Can anyone help me modify that for Cocoa on Mac?
Thanks,
David
Like this!
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
return count;
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSView *customView = [tableView makeViewWithIdentifier:#"customview"
owner:self];
…… // set properties
return customView;
}
In interface builder, set the identifier of your custom cell view to "customview" and it will automagically be created! Example:
Just replace "Automatic" with the identifier you are using

How do you make a row in a table view go slighly see through if a checkbox in that row is checked?

I am looking to make a Application and each row of the table view will have a column with a check box. What i am looking to do is... make the row that the checkbox is on go slightly see through if the check box on that row is checked (this should be implemented on every row of the table as every row has a checkbox) .
In your table view delegate, implement this method:
tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
From there you can get the checkbox button cell at the given row, and change the cell's drawing style based on it's state. Keep in mind though that cells are re-used, so you'll have to set the cell style for both checked and unchecked states.
I'm not too clear on what sort of drawing style you're aiming for. Try with a basic NSTextFieldCell first and if you can't accomplish what you're trying to do, create an NSCell subclass and handle the drawing code yourself.
Do you really mean "opaque"? ("Slightly opaque" is a lot like "slightly pregnant.")
If you mean change the color, add javascript to the checkbox to change the background of the div containing the checkbox. Here's an example.

Updating NSTableView in an instance of NSCollectionViewItem

In my setup I have an NSCollectionView of volumes connected to the mac. For the NSCollectionViewItem's View I have an NSBox with an NSTableView inside listing the contents of that volume.
My problem comes when trying to add/remove items to the NSTableView. The NSBox seems to be initialised once, so there is only one NSTableView. This means that when I want to update the data inside the NSTableView I cannot call reloadData on an IBOutlet and have it update all the tables.
If I create an IBOutlet in a subclass of the NSBox, it is nil for the instance, so I cannot call it via that.
The closest I have come is by enclosing a #try #catch around the code that returns the object at a row in a column, an exception occurs because that item no longer exists, so I can grab the tableView and call reloadData, which seems to update that specific NSTableView.
The problem with this is that if the item removed is at the end of the table, or if an item is added, the exception won't occur as it can see all the existing items.
Has anyone had any experience with an NSTableView on an NSCollectionViewItem's View? How did you update the tables?
Put the NSBox (with its NSTableView) into its own nib. Each time you create a new collection view item, load the nib, set that NSBox as the collection view item's view, and release the NSBox.
As for feeding the table views, the easiest way is probably Bindings. Bind each column of the table view to a different property of the model object that the collection view item represents. You'll probably want to go through an array controller, of course, which means having one of those per collection view item, and adding them to an array, which you'll release in dealloc.

Resources