OK, so I have an NSOutlineView
(populated via NSTreeController
).
Now this Outline View is View-based.
I've added 2 buttons inside the Table View Cell and assigned them 2 actions (as one would normally do).
However, none of them is being called when I click the buttons.
What is going on? Or - better phrased - what could be going on?
(This one definitely came as a surprise - since I must have done similar things more than 1 million times...)
The problem is that the cell views in a view-based outline view are actually in a sub-NIB. This isn't shown in IB, but the view hierarchy inside a column is a NIB unto itself. It's archived into a blob and that's embedded in the NIB that contains the outline view.
Because of that, you can't really connect actions, outlets, or bindings to most of the objects outside of the column. It's basically a bug in IB that it even allows you to do this. The connections won't be restored properly when the sub-NIB is loaded to create views for the outline view.
There are a couple of exceptions. The standard placeholders are identified in a NIB by special object IDs. If you connect an object in a sub-NIB to a placeholder, the connection is recorded as being to that special ID. When the sub-NIB is loaded by the outline view, the connection is actually made to the object which fills the role for that placeholder. The application object is unambiguous; it will be the actual application object. The first responder is actually nil
, so that continues to work. The iffy one is File's Owner.
You might think that File's Owner is whatever was specified as the owner of the outer NIB, but that's not so. When the sub-NIB is loaded, the outline view calls the delegate method -outlineView:viewForTableColumn:item:
. That normally calls -makeViewWithIdentifier:owner:
on the outline view. The owner passed as the second parameter of that call is what serves as the File's Owner for the sub-NIB. (If the delegate doesn't implement -outlineView:viewForTableColumn:item:
, the outline view passes its delegate as the owner.)
It's not clear to me if your outline view is in your main NIB or storyboard or, if not, what the AppDelegate you refer to might be. But if you're connecting your button's action to anything outside of the column that's not a standard placeholder object, the connection won't be restored properly when the sub-NIB is loaded. And even if you connect to File's Owner, you may get an unexpected connection.
A few possible solutions:
-outlineView:viewForTableColumn:item:
;
have it call -makeViewWithIdentifier:owner:
as normal to get the view; if the button isn't the cell view itself, find it via custom outlets on the actual cell view or a tag; and set its target to the desired object (like self
).NSTableCellView
, then you can subclass that, implement an action
method on it, connect your button to that, and have that action
method forward along to another object. You'll have to find the
ultimate target in code because you can't connect any outlets of
NSTableCellView
to outside objects any better than you can the
button's.NSTableCellView
's objectValue
somehow. Or go through
the application placeholder, via its delegate
property. Or
something like that.