Re: How does Apple want us to deal with custom elements in Xcode 4, with IBPlugins having been killed?
Re: How does Apple want us to deal with custom elements in Xcode 4, with IBPlugins having been killed?
- Subject: Re: How does Apple want us to deal with custom elements in Xcode 4, with IBPlugins having been killed?
- From: email@hidden
- Date: Thu, 18 Aug 2011 11:47:35 +0200
Am 15.08.2011 um 22:53 schrieb Sean McBride:
> On Sun, 14 Aug 2011 10:53:28 -0700, Chris Hanson said:
>
>> If you're targeting Mac OS X 10.6 or later, you can set arbitrary
>> properties on your objects in Interface Builder that will be set via KVC
>> at nib load time.
>
> I just discovered this last week. Are they guaranteed to be set before/after awakeFromNib, viewDidLoad, etc.?
>
> But what about bindings? If a custom view exposes additional bindings, how can one connect them in IB? As best as I can tell, you can't. I'd love to be corrected!
You can somewhat connect them. You cannot do everything in IB, but you CAN write the bindings in the .xib file since it's just XML and the format isn't too complicated. And if you did construct them correctly in the .xib file IB will also show them in the bindings inspector and allow you to change them partially (only one side of the bindings, the one where you would type in the binding in IB anyway).
One way to modify as little in the .xib file as possible is the following:
1. Find a property that is an exposed binding of a superclass of your custom class that IB knows about. Often you want to bind view properties to something and for NSView you can bind the "toolTip" property, so most of the time you can use that.
2. Enter a binding for this property to the object and key path you want to bind your custom property to.
3. Open the .xib file in an XML editor. Search for your keypath (often the easiest way to find your binding, if the key path is sufficiently long to be unique or will only appear a few times). You will find an entry like this (this one is an example from one of my nibs, a binding to an NSCollectionViewItem):
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">toolTip: representedObject.classDisplayName</string>
<reference key="source" ref="931629533"/>
<reference key="destination" ref="911180973"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="931629533"/>
<reference key="NSDestination" ref="911180973"/>
<string key="NSLabel">toolTip: representedObject.classDisplayName</string>
<string key="NSBinding">toolTip</string>
<string key="NSKeyPath">representedObject.classDisplayName</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">457</int>
</object>
4. Replace the occurrences of "tooltip" with the property you want to bind to. (I think it's only possible to have a property name here, not a key path)
There should be 3 occurrences, 1 in the <string key="label"> elemement (before the : ), one in the <string key="NSLabel"> element and one in the <string key="NSBinding"> element.
Make sure that there are no spaces around your properties, because the nib unarchiver will treat everything between the opening and closing element of <string key="NSBinding"> as part of the property name so <string key="NSBinding">toolTip </string> would mean the property "toolTip " which is not there and you would get a non-key-value compliant or does-not-respond-to-selector exception when loading the nib.
5. Open the nib in IB again. You should now see that toolTip does not have a binding any more, but there is a new entry for your property. You can change the key path as you like and also set value transformers and stuff like that and IB should change the xib accordingly. Only for hanging the property you would need to go back to the xib. Removing the binding should just work by unchecking the checkbox, but I have to say I never tried that yet. ^^
You can also create such a binding completely yourself. Just find another IBConnectionRecord of type IBBindingConnection (there are other ones for outlets and similar stuff) and copy it. (Or take the one above, but then you have to find the right position in the xib file).
This time you have to change more.
1. You have to change the <reference key="source" ref="931629533"/> and <reference key="NSSource" ref="931629533"/> to the ID of the object that should have the binding in IB (the one that would be the receiver of "bind::::"). Be careful this is not the Object ID shown in the identity inspector of IB. This object ID usually has around 3 places, but the id you need here has more like 9 places. But you can use the Object id to find the ID in the .xib. Just search the document for it until you find something like (again an example from my xib, an NSCollectionViewItem):
<object class="IBObjectRecord">
<int key="objectID">343</int>
<reference key="object" ref="911180973"/>
<reference key="parent" ref="0"/>
<string key="objectName">Incoming Stack Collection View Item</string>
</object>
The ref-Value in <reference key="object" ref="911180973"/> is the one you need.
2. Do the same for the <reference key="destination" ref="911180973"/> and <reference key="NSDestination" ref="911180973"/> ids and replace them by the ids of your target object.
3. Change the <string key="NSBinding">toolTip</string> to the property you want to bind to on the first object (the "binding" parameter in bind::::). Also change the part before the : in <string key="label"> and <string key="NSLabel"> to be the same as your binding value.
4. Change the <string key="NSKeyPath">representedObject.classDisplayName</string> to the keypath you want to bind to on the second (the target) object. (The keyPath parameter in bind::::). Also change the part after the : in <string key="label"> and <string key="NSLabel"> t be the same as your keyPath value.
5. Change the number in <int key="connectionID">457</int> to something unique (often it's enough to increment it by one).
6. Find an entry like this in the .xib (there should be only one): <int key="maxID">657</int> Make sure the maxID given there is higher (equal might be enough, more doesn't hurt) than your maximum connectionID.
7. Open IB and check that your bindings is displayed correctly in IB.
You usually get compiler errors if your connectionID is not unique or the maxID value is incorrect. It might also already break when you open it in IB again.
It might be a good idea to close the .xib in IB while you're fiddling with the raw XML. Oh and keep a backup at least the first few times (or just have version control).
Have fun fiddling with your .xibs. ^^
Joachim
_______________________________________________
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