How to connect outlet in a table cell view? - macos

I am using a view-based table, and I want to create an outlet for an element in a cell view. I cannot get the outlet to connect though... it's always nil.
Specifically, I have a NSProgressIndicator in a table cell and want to manipulate it in code.
Here's what I have so far:
I have created a subclass of NSTableView, with the corresponding outlet property:
#interface MyTableCellView : NSTableCellView
#property IBOutlet NSProgressIndicator *myProgressIndicator;
#end
#implementation MyTableCellView
-(void)awakeFromNib
{
// _myProgressIndicator is nil!
}
#end
And I have set the custom class in the nib. The existing NSTableCellView is replaced with MyTableCellView via the dropdown.
At this point, some observations:
If I Ctrl+Click and drag the progress indicator to connect this outlet, it is not shown.
Likewise, if I try to Ctrl+Click and drag the progress indicator using the assistant editor, I can only connect to the property via binding. It doesn't recognize this as a valid outlet.
However this outlet IS shown on the sidebar, with a warning that it doesn't exist:
I know MyTableCellView is being used. Breakpoint on awakeFromNib confirms this, and confirms that _myProgressIndicator is nil.
This is a sandbox project, with barely more than what I've described.
SO, how do I access this progress indicator from code?

I don't believe you should do it that way; instead:
Modify the model object used by the table view's data source to populate the table view.
Call the table view reloadData (or better reloadDataForRowIndexes:columnIndexes:).
Therefore you should only need an outlet to the table view to do this and any modification of the table view's cell objects should be done within the table view delegate and/or data source methods.

As described in the question, the usual method to connect outlets in Interface Builder does not work (maybe it is fixed in a recent version of Xcode, I am still using a version earlier than 6). Anyhow, it does work via the Connections Inspector.
Create an IBOutlet in your subclass of NSTableCellView.
In your XIB, from Identity Inspector, change the NSTableCellView to your subclass.
From Connections Inspector, drag from your outlet to the View object.

Related

NSTableView IBOutlet clickedRow is always -1

I have a problem with getting the clickedRow set through IB.
Setup
In IB I have a view with custom class set, call it MyView. The file's owner of the XIB is MyVC.xib. In IB I have also created an NSTableView inside MyView.
Thus the view hierarchy is like so
MyView -> (auto-generated) NSScrollView -> NSClipView -> NSTableView.
The tableview is setup through bindings and connected the double-click action/target correctly, as mentioned in this post Double click an NSTableView row in Cocoa?
I have declared and connected an IBOutlet NSTableView in MyVC.h.
Problem
When the selector is called, the NSArray of objects are passed in nicely. However, I cannot know which of them to operate in since [_tableView clickedRow] always returns -1.

How to set view outlet for a UITableViewController?

I created an empty xib, I dragged a UITableViewController, set Custom class to my class that extends from UITableViewController at both the UITableViewController and File's Owner.
When I run, it says:
'A view can only be associated with at most one view controller at a time! View ; layer = ; contentOffset: {0, 0}> is associated with . Clear this association before associating this view with .'
At connections inspector I see that the UITableViewController element has:
tableView - Table View
view - Table View (greyed)
dataSource - Table View
delegate - Table View
First Responder has nothing.
File's Owner has:
tableView is not attached to anything
view - Table View
If I remove the view connection at File's Owner, it claims that the view outlet is not set.
It is difficult to imagine what happens based on the information provided. However:
The error message says that you have a UIView, and you try at runtime to connect this UIView to two UIViewControllers, which is not possible.
If you just subclass a UITableViewController, without adding properties or implementing methods, then setup a UITableViewController in an empty storyboard, and set the class of this UITableViewController to your subclass, you have only a single UITableViewController, and you will not get this error.
So somewhere in your project you must instantiate a second UITableViewController programmatically, and set its UIView property (which is a UITableView) to the UIView of the other UITableViewController.
You should ensure that you have only a single UITableViewController, namely your custom subclass.
I guess the correct answer is DON'T drag UITableViewController to the interface builder. Have 2 IBOutlets connected, one for the view, one for the table. DO drag a UITableView instead.
Hope this helps other people.

Can't CTRL+Drag NSButton to custom NSView header

I'd like to create a custom NSTableCellView instantiated by Interface Builder. I've set my Table Cell View class to MyTableCellView, and properly created MyTableCellView : NSTableCellView .m/.h files.
However, I just can't CTRL+Drag a simple button from inside this view to MyTableCellView.h in order to create an IBOutlet.
Here is a video to show what happens: http://youtu.be/sNNbuVT-SZs.
How the view is subclassed:
How I try to CTRL+Drag a button
Also, sometimes, Interface Builder just don't allow the cell view's class to be modified. What's happening ?
I finally found a solution, that is a little weird but works as expected. Instead of connecting the NSButton to MyTableCellView header directly, I used the reversed path:
Manually create an outlet:
#property(retain, nonatomic) IBOutlet NSButton* button;
Then click the empty circle on the left, and drag it to your XIB file's button:
I have no idea why it works this way, please let me know if you know the anwser.

Can I use NSViewController to provide a reusable NSTableView with defined columns and data?

I'm fairly new to Xcode and Cocoa development, so please excuse me if I use the wrong terminology.
I have a window which has an NSTableView bound to a NSArrayController. The NSTableView has some predefined columns and the NSArrayController is populated with data when my window is loaded.
This all works fine, but I now need to re-use the functionality in a number of other windows.
After much reading I think and NSViewController is what I need, to provide an object that I can re-use in different windows in multiple .xib.
So what I have done is created a new NSViewController sub class in Xcode which also created a new xib for that controller.
The xib contains a custom view, where I have placed my NSTableView.
#interface KeyViewController : NSViewController
#property (weak) IBOutlet NSTableView *keyTable;
#end
The files owner class is set to the KeyViewController, and the view outlet is set to the files owner.
I then placed a ViewController object into the original window and hooked up the view to a new custom view in the window
I then set the nib name for the ViewController in its properties.
The new view never gets displayed and the view controller initWithNibName never gets called.
Am I missing something vital or missing the plot completely. Should you be able to do this just with interface builder or do I need to alloc and init the view in code?
If I do have to do it in code, whats the purpose of the ViewController object in IB and the Nib Name property for it?
Thanks..

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.

Resources