iOS – Implementing Themes for View Controllers

designiosobjective c

I have an application, where font size, font type, color, background color, image and a lot of things change based on theme.

I realised in the beginning itself that using enums to denote themes and then checking the theme everywhere was a horrible mistake.

So I have two approaches now and I am confused which one to go with.

Keep a Base View Controller for my app with default look and feel of the application and then create a subclass per theme.

Or

Create a Theme class which will provide theming information and then subclass it per theme and set the theme Object on the view controller and query theme object before applying the theme.

Or

There could be another approach I haven't thought about 🙂

Best Answer

You're right to want to change technique. You can imagine all the work you'd have to do everytime you need to add a new theme.

Subclassing View/Controller

Some programmers may choose to subclass the base view controller in order to take into consideration multiple themes. If the adaptations you have to apply between theme to theme is radically different, then this approach is fine. However, most times themes share a lot of common features, and you may end up having to change very little between them.

Subclassing Theme

The second approach eliminates this problem by having a shared "theme" class which does a lot of the work common among themes. It also keeps your view class single-purposed (and therefore easier to read) and doesn't have to worry about little nuances like theme changes. Since this approach eliminates all the disadvantages of the 1st approach with no added disadvantages of its own (unless "excess classes" is something you consider a disadvantage), this approach is the best practice in general.

Do the best you can to use inversion-control principle and have your view/controller call the theme class in order to do theme-specific tasks like draw a control, passing all the necessary information about said control into the method. In this way, your theme is stateless and you retain control in your controller without having to know how it works. Plus, you can have a base theme behavior in your basic theme class so you even if you do not override method, you're sure to always see something, even if it may not be themed properly.

I hope that helps.

Related Topic