MVVM – Who Sets Color in iOS?

division-of-laboriosmvvm

I have an iOS app where after exceeding a certain limit, part of the user interface changes a color to alert the user. I'm using MVVM to accomplish this and division of labor looks like this:

Model – fetch limit value and from the storage

View Model – compare limit with current value and pass bool (over/under limit flag)

View – pick a color based on the limit flag and set it on required views (this work is done in a controller).

I started to wonder if selecting color for the views isn't a view model's job. If you divide MVVM to M(VC)VM, maybe it can be fitted into a UIView's subclass instead of UIViewController's. Where is the place for selecting an actual color? And why?

Best Answer

The View is the place which has intimate knowledge of your graphical runtime environment, of how color is expressed in it, and even of the fact that you are actually running within a graphical runtime environment and not as part of some unit test. (Assuming that you unit-test your Model, and your View Model, but not your View.)

So, I would think that the View is the best place for converting the "over the limit" flag to a color, so that your unit tests only need to ensure that under the right conditions, the "over-the-limit" flag is raised in your View Model.

On the other hand, if you want to give the user the ability to choose the color to display in case of an "over the limit" situation, then the color becomes part of your Model.

However, even in that case, the color chosen by the user in the event of an "over-the-limit" situation can be presented by the View Model as a completely separate entity from the "over-the-limit" flag itself, and in a completely abstracted fashion, (say, a string containing a color name,) rather than as the actual RGBA value which your runtime environment requires.

Let the View read from the View Model the "over-the-limit" flag, and if it is set, then let it also read the abstracted color which is to be displayed in this situation, and let it worry about converting the abstracted color to an RGBA value.