Re: Bindings in view-based tables
Re: Bindings in view-based tables
- Subject: Re: Bindings in view-based tables
- From: Ken Thomases <email@hidden>
- Date: Thu, 05 Mar 2015 19:06:48 -0600
On Mar 5, 2015, at 6:09 PM, Shane Stanley <email@hidden> wrote:
> On 6 Mar 2015, at 10:32 am, Quincey Morris <email@hidden> wrote:
>>
>> Er, what exactly was bound to what?
>
> In the cell-based table, the table's (sole) column's Font Size is bound to the shared user defaults controller with a Controller Key of values and Model Key Path of tableTextSize.
>
> The buttons are in a radio group, with the Selected Tag bound to the same thing. (The two buttons have tags of 11 and 13 respectively).
The views within a table column for a view-based table view are weird. They look like they are just part of NIB that you're working on, but they're really in a sub-NIB. Basically, there's a NIB that's been archived to a data blob and stashed in the outer NIB.
This is sort of exposed in the way that -makeViewWithIdentifier:owner: takes an owner parameter and makes that object the owner of the cell view NIB.
Often, you don't need to know about this NIB-within-a-NIB business. However, it becomes important when you try to establish connections (target-actions, outlets, and bindings) to objects outside of the sub-NIB. Basically, it's not possible.
I _think_ connections to File's Owner are restored when the cell view NIB is loaded, but the File's Owner of the sub-NIB may not be the same as the File's Owner of the outer NIB. It may not even be the same class. It may also work to connect to the Application placeholder; haven't checked.
However, it doesn't seem to work to connect to the Shared User Defaults Controller, as you've discovered. The connections are lost if you're lucky. If you're unlucky, maybe they end up connected to some other object if object IDs in the NIB collide. (Object IDs as shown in IB seem to be generated in a way that makes it unlikely they'll collide, although I don't know if the IDs shown in IB and stored in the .xib file are carried over to the compiled .nib. Compiling may convert the IDs to sequentially assigned integers starting at 1, for example.)
Unfortunately, the solution is clumsy. You have to use a separate view NIB for the table cell view. That means you can't really design the view-based table in the NIB that contains the table view. The table view is in one NIB and the cell views are in other NIBs.
Build a view NIB that contains your cell view. Set the identifier of the table column in the table view NIB and set the identifier of the cell view in the cell view NIB to the same value. You can no longer rely on Xcode setting those up to match automatically.
It seems you can't delete the cell view that's under the table column in the first NIB. Or, rather, you can, but Xcode will replace it with a new basic cell view the next time you open the NIB. You can ignore it or, if you're paranoid, set its identifier to something that doesn't match the column's identifier.
In the cell view NIB, you can bind the text field within the cell view to the Shared User Defaults Controller. This binding will survive, because the object that you've connected to really is in the same NIB as the text field, as opposed to just looking like it is.
Now, in your table view delegate, you need to add some code. At some point before the first call to the table view's -makeViewWithIdentifier:owner: method with your column identifier, you need to load your cell view NIB as an NSNib object and pass it to -registerNib:forIdentifier:. So, something like:
if (!self.registeredNib)
{
NSNib* nib = [[NSNib alloc] initWithNibNamed:@"TableCellView" bundle:nil];
[tableView registerNib:nib forIdentifier:@"MyColumn"];
self.registeredNib = YES;
}
You only need to do this once for any given column identifier/cell view NIB combination. Actually, your cell view NIB can contain multiple cell views, each with a different identifier. You can register that one NIB repeatedly, with each identifier, and the table view will pick the appropriate top-level view out of the NIB based on the view's identifier.
Putting that code in your -tableView:viewForTableColumn:row: just before you call -makeViewWithIdentifier:owner: on the table view is fine, if that's the only place you call that.
Hopefully that works for you. It worked for me in a test app where I had a text field outside of the table and one inside a cell view, both bound to the same key in the user defaults. Editing one changed the value in the other, as desired.
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden