Search code examples
cocoapropertiescocoa-bindings

What's the best way to add a composite property for binding to an existing class


Let's say I have a Size class which has height and width properties (in reality the class is a bit more complex than this, but Size makes a good example).

I want to display this as $width x $height in my UI.

The obvious way to do this is to bind to a dimensions property which is dependent on width and height.

My question is where is the best place to add this new property?

I could add it to the Size class itself in the modal, but then if another controller wants to display the string different I'm stuck creating yet another property. I'm also a bit reluctant to do this because in my case the Size class is in a framework that will be used in a couple different places (although likely all from code I have control over).

I could add it in a category to the Size class inside the project containing the view/controller so it will only be availiable in the places I know it will be used, but in various places I've seen suggestions that categories tend to be overused, and am forced to wonder if this is one of those cases.

In the case of a single Size instance I could create the property in the controller class containing it, but this becomes more difficult when you have an array of Sizes.

I could bind to the entire size object and use a transformer to turn them into strings, but binding to an array of sizes would then cause you to have to transform each element of the array into a new array in the transformer, which seems a bit ugly.


Solution

  • If want to display this composite value as a string, then bind "Display Pattern 1" of a text field to the width property and "Display Pattern 2" (shown when you bind Display Pattern 1) to the height property. In the Display Pattern 1 binding, set the "Display Pattern" to %{value1}@ x %{value2}@ (yes, slightly unintuitive syntax). This will give a text field that displays "[width] x [height]" and will update on changes in either property.

    You can do the same with an NSTextFieldCell, e.g. as the cell in an NSTableColumn. The downside of this method is that the text field will not be able to edit the bound width and height values. You would have to write an NSValueTransformer if you need to be able to edit them.