views:

105

answers:

3

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.

A: 

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

Why not two fields? Then you could make them editable.

(in reality the class is a bit more complex than this, but Size makes a good example)

Assuming the above is not feasible in your real situation, you might try creating a custom subclass of NSFormatter, and setting it as the formatter on the cell (I assume this is in a table view, since you wouldn't bind a single control to an array). You would then bind to whole Size objects.

Peter Hosey
+3  A: 

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.

Barry Wark
I actually have no need for these fields to be editable, so that will be ideal. Thanks!
Lawrence Johnston
+1  A: 

Using multiple bindings through a display pattern as Barry suggested sounds like the best approach, at least without knowing more about your UI. I've used the same thing in the past, where I built an inspector for an array of images and had the dimensions bound to a single text field.

In general it's good practice to use value transformers or formatters if you can, but in cases of last resort there's nothing wrong with using a category. I've done this in the past when I had trouble binding to a date, but breaking it down into individual time and date pieces. A category is a good approach because it lets you maintain separation with the model, but you don't need to do anything crazy like binding directly to the controller.

Marc Charbonneau
Thanks for the insight.
Lawrence Johnston