App Theming in Swift
A few years ago I landed my first iOS contracting role. I was in my freshman year of college and excited to have my first professional software development experience.
My eagerness to immediately start the development in lieu of properly planning the application cause a lot of rework later on — primarily due to changes in the application’s theming.
During the contract, I can remember the theming of the iOS application changing seemingly every other day. I’d inevitably wake up with an email asking for all of the font sizes to be one point larger, a different text color, different font entirely, etc. After making the changes manually one too many times, I started using the following structure to consolidate all of the application’s theming properties.
Setup
First, we’ll create a Theme class to manage all of our constants, custom colors, custom fonts, and our default styling of UIKit components.
import UIKitclass Theme {}
Within our Theme class, let’s add the following Constants class to add support for our custom UI related rules.
Now, leveraging Xcode’s “Asset Catalog” color functionality we can define our brand colors by their hex value in Xcode directly and give them a name of our choosing.
We can add support for our custom fonts in a similar way. This approach also allows us to easily provide a default font in case an issue arises with our custom font.
At this point, we can reference our custom colors and fonts anywhere in our application with Theme.Color.brandDarkBlue and Theme.Font.regular(size: 18.0).
If the design requirements were to change, we simply make the relevant changes in the Theme class and the entire application will style accordingly.
Additional Functionality
We often use UIApplication, UINavigationBar, etc to establish custom styling across the application. For example, changing the status bar color and the styling of the navigation bar:
However, we don’t want to bloat our AppDelegate’s didFinishingLaunching() with these declarations, so instead we’ll move this to our Theme class.
And in our AppDelegate’s didFinishLaunching(), we can simply add Theme.setAppearance() to apply our custom theme before the first view controller is presented.
Additionally, we can add some helper methods to our Theme class in order to add some custom styling to other UIKit components.
Then, where relevant, you can apply this custom styling simply with Theme.apply(to: navigationBar)
Conclusion
- Makes changing the styling of the application trivial.
- Minimizes merge conflicts.
- The same theme can be easily re-used in other applications.
- The check for a valid custom font only occurs in one location and provides an easy option for providing a default font if the custom font is unavailable.
- The styling of the application is now very extensible. You can very easily add more fields.
- Increases code quality and readability.
- You can optionally create a Theme protocol that would allow multiple different theming opportunities. For example, a day/night mode, guest/authenticated user, admin/regular user, etc. You could use an extension on the protocol to provide some default values and customize the other properties when relevant.
- You could add Codable support to the Theme class allowing the back-end to specify the styling of the application. This is particularly useful for applications that are white-labeled or instances when your brand guidelines / design language are still developing.
If you enjoyed this article, check out my other iOS content!
https://medium.com/@aryamansharda/imessage-stickers-remote-images-analytics-9a4933e76055