Reusability in view layer (An iOS architecture part III)

The aim of this post is to reinforce the reusability in view layer, it will be presented a way to handle the fonts (and its sizes), colours, texts translations and accessibility labels (for automated UI tests).

This post is the continuation of  the view layer (an iOS architecture part ii) and part of it is based on the following presentation but supported with a sample project in case you want further investigation or adopt the technics explained in your projects.

The view layer (An iOS architecture part II)

Fonts (and its sizes)

For better folder organization we have placed the font files into ViewLayer/Resources/Fonts:
☝️Do not forget add the resource to project target:

Also do not forget to add the fonts also in the Info.plist:

Edit the Info.plist and add the following chunk of xml:


The helper for the font sizes is placed at ViewLayer/Resources/Styles:

For each presenter we have defined an structure that gathers the fonts that is using, this approach lets you have centralised in a unique file the font definitions for WHOLE app:

struct ArchTempFonts {
    struct MostPopular {
        static let PlaceCountryFont   = TextStyle.h20Book.font
        static let BoteUpButtonFont   = TextStyle.h36Book.font
    struct LatestPlace {
        static let CountryFont  = TextStyle.h36Book.font
        static let PlaceFont =  TextStyle.h20Book.font

I let the reader to download the sample project and review the rest of structures contained in the file for further understanding.

Finally for setting the file in the outlet is as simple as:

lblName.font = ArchTempFonts.LatestPlace.PlaceFont

And the result is the following:


For colors we will use the same approach as in fonts, define a helper in Styles folder:

As well as in fonts  we will define the palette of colours used as well as the palette-dolors used by each presenter:

struct ArchTempColors {
    private struct Palette {
        static let Grey = UIColor(rgbaValue: 0x888888FF)
        static let Brown = UIColor(rgbaValue: 0xC48764ff)
        static let Crimsom = UIColor(rgbaValue: 0xce2124ff)
        static let Water = UIColor(rgbaValue: 0x5085DEff)
    struct MostPopular {
        static let PlaceCountryFontColor   = ArchTempColors.Palette.Grey
        static let BoteUpButtonFontColor   = ArchTempColors.Palette.Brown
    struct LatestPlace {
        static let CountryFontColor  = ArchTempColors.Palette.Crimsom
        static let PlaceFontColor    = ArchTempColors.Palette.Water

Finally for setting the color in the @IBOutlet:

lblName.textColor = ArchTempColors.LatestPlace.PlaceFontColor

And the result is the following:


We have just created a string extension for automatically handle the translation depending on the project language bundle:

extension String {
    var localized: String {
        if let _bundle = self.getCurrentBundle() {
            return NSLocalizedString(self,
                                     tableName: nil,
                                     bundle: _bundle,
                                     value: "",
                                     comment: "")
        } else {
            return ""

For avoiding the problem of text identifiers during execution time, we use R.Swift so during compilation time we will know if resource really exists or not. This is also very useful for images, cell reusability, segue identifiers… In that way you will avoid bugs related with identifiers that do not match with the resource. 🚑 Really, do not hesitate in incorporate this pod in your projects!!!!

Finally for set the texts is as easy as:

self.tabBar.items?[0].title = R.string.localizable.home.key.localized//"_Home"
self.tabBar.items?[1].title = R.string.localizable.mostPopular.key.localized//"_Most Popular"

Even that constants has 6 elements in the keypath, 5 of them are always constant: R.string.localizable.<textId>.key.localized

Accessibility labels

iOS developer will not get direct benefit in setting accessibility labels to @IBOutlets, but when there  is a test team for handling UI tests we have to facilitate their job. In return we will have quick and precise bug reporting. All in all this will save you time in middle-long term.

As well as in fonts and colors, we will create a new module that will concentrate all accessibility constants:

With the following structure:

struct Accessibility {
    struct MostPopular {
        static let PlaceCountry   = "MostPopular.PlaceCountry"
        static let VoteUpButton   = "MostPopular.VoteUpButton"
    struct LatestPlace {
        static let Country  = "LatestPlace.Country"
        static let Place =  "LatestPlace.Place"

Finally for applying accessibility to @IBOutlet:

lblCountry.isAccessibilityElement = true
lblCountry.accessibilityIdentifier = Accessibility.LatestPlace.Country


With this and previous post we consider the view layer of the architecture already presented. If you have any doubt, and you can download the source sample project from here.

What’s next

In the next post will be presented the Domain Layer and how View Layer interacts with it using UseCases (Interactors in Viper) and Coordinators.