6

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. enter image description here enter image description here

  • 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. enter image description here

  • However this outlet IS shown on the sidebar, with a warning that it doesn't exist: enter image description here

  • 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?

tenfour
  • 36,141
  • 15
  • 83
  • 142

2 Answers2

2

I don't believe you should do it that way; instead:

  1. Modify the model object used by the table view's data source to populate the table view.
  2. 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.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • You are describing binding, but some things are not possible via binding. For example to send `startAnimation` to a progress indicator. – tenfour Jan 15 '14 at 11:48
  • @tenfour No, this is not binding. It's MVC where you modify the Model and the Controller modifies the View (via delegate/datasource methods). This is the straight forward programmatic method of using a table view and binding is something else. – trojanfoe Jan 15 '14 at 11:50
  • @tenfour To add to my comment, you can easily send a `startAnimation` message to the progress indicator from the delegate/datasource methods. – trojanfoe Jan 15 '14 at 11:54
  • I don't understand; on which object can you send `startAnimation` to if you have no `NSProgressIndicator` reference? – tenfour Jan 15 '14 at 11:56
  • @tenfour As part of the `NSTableViewDataSource` protocol (`tableView:objectValueForTableColumn:row` etc). You decide what class object to use to represent a table view cell and you should be able to get a reference to it after setting it. – trojanfoe Jan 15 '14 at 12:06
  • I understand the MVC model object, but there is still no way to get the `NSProgressIndicator` reference. `[????? startAnimation];` – tenfour Jan 15 '14 at 12:17
  • @tenfour I think you should start a new question with the details of what you are *now* doing to populate the table view. – trojanfoe Jan 15 '14 at 12:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/45280/discussion-between-tenfour-and-trojanfoe) – tenfour Jan 15 '14 at 12:33
1

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.

  1. Create an IBOutlet in your subclass of NSTableCellView.
  2. In your XIB, from Identity Inspector, change the NSTableCellView to your subclass.
  3. From Connections Inspector, drag from your outlet to the View object.
Jerry
  • 966
  • 2
  • 13
  • 28