Possible to use NSView subclass in NSTableView? - cocoa

I have an NSView subclass that I'd like to use in an NSTableView. Normally of course I'd use a NSTableCellView subclass but this view will be used elsewhere.
Possible?

There's no requirement that the cell view used for a view-based table view be an NSTableCellView or subclass. It's perfectly OK to use an instance of some other view object. For example, an NSTextField works out of the box.
Your table view delegate's -tableView:viewForTableColumn:row: method can configure the view as appropriate for the row. Or, your view can implement an objectValue property (with -setObjectValue: setter). In this case, the table view will forward whatever object value your data source returns from its -tableView:objectValueForTableColumn:row: method to your view's objectValue property.
Also, if your view class has textField or imageView properties (like NSTableCellView does), then those will be treated specially in certain cases. For example, the text field will be the accessibility string for the cell.
Basically, all of the behaviors of NSTableCellView are generalizable. It's not that the class is treated particularly specially by the framework. It's that it provides the appropriate properties and methods and any view with those same properties and methods could replicate its behavior.

Change your NSView subclass to inherit from NSTableCellView instead of NSView, since NSTableCellView also inherits from NSView too.

Related

NSOutlineView (or NSTableView) with custom NSTableCellView doesn't create connections to outlets

A .nib file contains NSOutlineView (1-column, view-based). Column has identifier "UserCell"; it also has one cell which has two NSTextField's and bunch of buttons; this cell also has identifier "UserCell". Class for this cell is set in IB to be a custom class derived from NSTableCellView class. I option-dragged both NSTextField's to the custom code (see picture attached) to create IBOutlets.
In delegate's method -outlineView:viewForTableColumn:item: I load cell using -makeViewWithIdentifier:owner: and it loads fine - I get my custom cell view object. However, both text fields are nil's.
How one should fix it? The same story with NSTableView.

Bindings for custom views for NSCollectionViewItem

I've got a NSCollectionView bound to my array of model objects, the NSView prototype to render items of the collection view is set up to use my custom NSView subclass.
At runtime a (generic) view is shown/instantiated in the collection view for each array element, all good.
However, I just can't figure out how to get to my array objects from the individual view instances to render the actual data that's specific to each element in the array.
I.e. how are we supposed to hook up data to the NSView prototype that is used to configure a 'cell' in the collection view?
Outlets don't seem to work for that particular view; they're all nil at runtime.
Bindings don't work with a vanilla NSView (apart from hidden and tooltip bindings for vanilla views..) - and we cannot add new bindings that would show up in IB for our NSView subclasses, can we?
Any hint appreciated!
Nevermind - I've settled with a custom NSCollectionView class overriding only
- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
to access the item view of NSCollectionViewItem instances created by super and set the required property there.

Custom NSViewController representedObject doesn't update when view selection changes

I've got a custom NSViewController that's also an NSOutlineViewDataSource. I also have a window with an NSOutlineView bound to an instance of my view controller as the data source, and the NSOutlineView bound to the view: property of the custom view controller.
The controller fills the outline view fine. However, selections within the view don't automatically update the representedObject property of the controller. The only thing that seems to trigger a change in representedObject is when I call setRepresentedObject: directly... which sort of defeats the purpose.
Any idea why that might be? representedObject is supposed to update automatically, right? Thanks in advance...
If I understand your question, you are not understanding what representedObject is for. The representedObject is the model object that represents all the data that a view controller is displaying. It is not the current selection of a view showing a collection of content. The representedObject for your custom top level view controller would be an NSArray or other collection class which contains the set of data you are displaying in your view controller. Changing the representedObject for your custom top level view controller should have the effect of swapping out for an entirely new data set if the pattern is being used correctly.
Typically the view controllers for the individual elements in a tabular type view would each have their own representedObject and this object would not change. For example if you were using an NSCollectionView each element in the view is controlled by an NSCollectionViewItem which is a subclass of NSViewController. The representedObject for each NSCollectionViewItem tells it what data to present in its little view.
NSOutlineView and its superclass NSTableView are different in that their cells are often NSCells rather than full fledged NSViews unless you choose to use them this way in Mac OS X 10.7 or newer. Even in this case, you don't typically have an NSViewController subclass managing each cell. So the view controller representedObject pattern is not used at the level of the individual element that the user would select. If what you want is to track the NSOutlineView's selection, there are many NSTableView methods that let you do this.

How to get NSTableCellView of view-based NSTableView?

I've just created my first view-based NSTableView in Interface Builder and I've correctly set up the data source and the bindings to update the views in the tableview. Each view has two labels and a NSProgressIndicator. Updating the progress indicator through the bindings and the data source works perfectly, but I'd like to change its state from determinate to indeterminate at some time. As my NSTableCellView subclass has access to the progress indicator, how can I get access to the cell view at a given row index? I've tried calling viewAtColumn:row:makeIfNecessary: on the tableview with both NO and YES for the makeIfNecessary argument, but neither seems to work.
Solution 1: In your NSTableCellView subclass add a property (IBOutlet) for your NSProgressIndicator control. Wire it in IB to set the property when the view is loaded. You can then access the progress control in your cell view subclass by using the property.
Solution 2: In IB give your NSProgressIndicator a unique integer tag. In your cell view subclass use [self viewWithTag:] to get the object.
I am not sure about the answer to your main question but you can bind the indeterminate state as well. In IB Is Indeterminate is listed in the Parameters section.

How to add text to NSTableView

I made a Cocoa application that has an NSTableView, an NSTextField, and an NSButton. The user enters text into the text field and clicks the button. When the user does this, I want the text in the textfield to be placed in the NSTableView. I find that I can't even bind an IBOutlet to a cell in the NSTableView. What should be done?
The Model-View-Controller pattern, which is used extensively in Cocoa is your friend here.
What you need to do is to bind the NSTableView to an array (The model). Then configure the button so that a click tells the controller to add the content of the text field to the array and if the bindings are set up correctly the NSTableView (The View) will be updated.
What I think you need to do is make a class, AppController for instance which will be your data source and the delegate of the NSTableView. So you need the following.
Two IBOutlets (one for the NSTextField and one for the NSTableView)
An IBAction for the NSButton.
Make those connections in Interface Builder.
Remember to use the mandatory delegate methods (there are two of them) so you can add the data from your data source (usually a collection class..an array, dictionary...etc.

Resources