Theming

When using IdsvrHaapiUIKit in the application, UI components including ViewControllers are themed using colors, images, font, and UI configurations specified in a plist file. Everything that is displayed when performing an Haapi flow can be themed to some extent.

Each UI component uses its own style definition. A style definition contains keys and values. The latest are String, Number, Boolean, or Dictionary. When trying to change any aspects of the UI component as demonstrated below, it is important to fit the specification. Otherwise, the application may crash and if it is the case, please check the logs in the console.

How to override colors that are used in IdsvrHaapiUIKit?

In the application Asset catalog, define an existing key and provide a new color. Here is the list of colors that are being used.

For example, to change hui_background, declare the same key in the application Asset catalog and define the colors. When an UIComponent in IdsvrHaapiUIKit uses hui_background, it uses the ones declared in the application Asset catalog instead of the framework.

It is also possible to assign for the UIComponent in IdsvrHaapiUIKit, via a custom theme, to use a color that is not in the list. See below how to assign a custom theme.

How to override images that are used in IdsvrHaapiUIKit?

In the application Asset catalog, define an existing key and provide a new image. Here is the list of images that are being used.

For example, to change hui_ic_authenticator_user, declare the same key in the application Asset catalog and provide the image asset. When an UIComponent in IdsvrHaapiUIKit uses hui_ic_authenticator_user, it uses the ones declared in the application Asset catalog instead of the framework.

How to change the font in IdsvrHaapiUIKit?

IdsvrHaapiUIKit uses by default Roboto font.

If the current font does not meet your needs, it is possible to change it. There are 2 ways: existing font from the iOS system or custom font.

Using an existing font from the iOS system

In the iOS system, here is the list of supported fonts.

For example, to change the font to Baskerville, create a plist file in the application. In the plist file, add a new key of String named fontName.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>fontName</key>
	<string>Baskerville</string>
</dict>
</plist>

When using HaapiUIKitApplicationBuilder, the plist file name needs to be provided. For example, if the plist file is named: "MyCustom.plist". As explained above in the AppDelegate when using HaapiUIKitApplicationBuilder, a new method needs to be invoked.

HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // It referes to MyCustom.plist. 
.build()

Using a custom font

To use a custom font, here are the requirements:

  1. Add the files related to the custom font to the application workspace. The files need to be a ttf file extension and target the application workspace.
  2. Create a plist file in the application. In the plist file, add a new key of String named fontName. The value is the font family name using title case representation. For example, if the files were added and have the prefix, IBMPlexMono, then the font family name title case representation is IBM Plex Mono.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>fontName</key>
	<string>IBM Plex Mono</string>
</dict>
</plist>

When using HaapiUIKitApplicationBuilder, the plist file name needs to be provided. For example, if the plist file is named: "MyCustom.plist". As explained above in the AppDelegate when using HaapiUIKitApplicationBuilder, a new method needs to be invoked.

HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // It referes to MyCustom.plist. 
.build()

When starting the application with these changes, the logs should indicate if the custom font was added with success.

2023-08-10 21:32:18.512355+0200 IdsvrHaapiUIKitApp[36182:2904595] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.291 : There are initially 84 registered fonts.
2023-08-10 21:32:18.528310+0200 IdsvrHaapiUIKitApp[36182:2904595] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.305 : Now there are 86 registered fonts.
2023-08-10 21:32:18.529603+0200 IdsvrHaapiUIKitApp[36182:2904595] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.308 : These fonts were added: ["Roboto", "IBM Plex Mono"])

As shown above, the custom font "IBM Plex Mono" was added. (Roboto is the default font that is used in the framework.)

ℹ️ If the fontName was configured with IBMPlexMono instead of IBM Plex Mono. A warning will be displayed when the application starts as shown below. ⚠️ If the name is configured incorrectly, then the application crashes.

2023-08-10 21:50:51.418855+0200 IdsvrHaapiUIKitApp[37474:2932255] [HAAPI_UI_THEMING] [WARNING] ThemeRegistry.316 : The configured fontName is `IBMPlexMono`. Isn't it `IBM Plex Mono`?

⚠️ If the fonts were already registered in the application's project by declaring them in the application's info plist file as the example below.

<dict>
	<key>UIAppFonts</key>
	<array>
        <string>IBMPlexMono-Bold.ttf</string>
        <string>IBMPlexMono-BoldItalic.ttf</string>
        <string>IBMPlexMono-ExtraLight.ttf</string>
        <string>IBMPlexMono-ExtraLightItalic.ttf</string>
        <string>IBMPlexMono-Italic.ttf</string>
        <string>IBMPlexMono-Light.ttf</string>
        <string>IBMPlexMono-LightItalic.ttf</string>
        <string>IBMPlexMono-Medium.ttf</string>
        <string>IBMPlexMono-MediumItalic.ttf</string>
        <string>IBMPlexMono-Regular.ttf</string>
        <string>IBMPlexMono-SemiBold.ttf</string>
        <string>IBMPlexMono-SemiBoldItalic.ttf</string>
        <string>IBMPlexMono-Text.ttf</string>
        <string>IBMPlexMono-TextItalic.ttf</string>
        <string>IBMPlexMono-Thin.ttf</string>
        <string>IBMPlexMono-ThinItalic.ttf</string>
	</array>
</dict>
</plist>

The success log is different because ThemeRegistry does not need to register the custom font.

2023-08-10 21:56:09.982900+0200 IdsvrHaapiUIKitApp[37856:2940070] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.291 : There are initially 86 registered fonts.
2023-08-10 21:56:09.995493+0200 IdsvrHaapiUIKitApp[37856:2940070] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.305 : Now there are 87 registered fonts.
2023-08-10 21:56:09.996721+0200 IdsvrHaapiUIKitApp[37856:2940070] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.308 : These fonts were added: ["Roboto"])
2023-08-10 21:56:09.998978+0200 IdsvrHaapiUIKitApp[37856:2940070] [HAAPI_UI_THEMING] [INFO] ThemeRegistry.94 : ThemeRegistry is setup.

How to override the static texts used when handling the authentication flow?

In the application's localizable strings file, define an existing key and provide a new localized value text. Here is the list of key/value definitions that are being used.

For example, to change hui_done associated text value, declare the same key in the application's Localizable strings file and provide the desired value. When an UIComponent in IdsvrHaapiUIKit loads a localized string for the key hui_done, it uses the one declared in the application string definitions files instead of the framework.

The framework only bundles with localized definitions for the default language setting which is provided in English language.

How to identify which themable components are displayed?

The HaapiLogger requires to be configured:

HaapiLogger.followUpTags = [UIKitFollowUpTag.theming, UIKitFollowUpTag.component, UIKitFollowUpTag.layout]
HaapiLogger.isDebugEnabled = true

When running the flow, check in the console for the follow up tag: "HAAPI_UI_LAYOUT". Here is an example:

2023-08-08 23:43:10.820923+0200 IdsvrHaapiUIKitApp[24669:526101] [HAAPI_UI_LAYOUT] [DEBUG] HaapiFlowViewController.246 : Presenting <IdsvrHaapiUIKit.HaapiFlowViewController: 0x7f8230023200> can be themed and uses these themable elements: ["NotificationBannerView", "LoadingIndicatorView", "LoadingIndicatorView.ButtonPrimary", "LoadingIndicatorView.ButtonSecondary", "LoadingIndicatorView.ButtonText", "LoadingIndicatorView.ButtonLinkView", "StackView", "StackView.Interactions", "StackView.Links", "StackView.Polling"] - it is not an exhaustive list.

How to change the UI configurations?

Every UI component that is used in IdsvrHaapiUIKit can be themed. The theming is relying on a set of configuration that reference the color, image or primitive values such as String, Number, Boolean, etc. The set of configuration can be overridden by providing a plist file that overrides any specific keys with the corresponding values.

⚠️ Providing an incorrect value to a valid key may crash the application. Please check carefully the specification for the corresponding style definition.

Here is the list of style definitions for every UI component.

Here are a few examples:

Changing UICTFontTextStyleBody

UICTFontTextStyleBody is a key that represents the font size. This key is being used by many UI components. In IdsvrHaapiUIKit, the value is 17.

How to change to 15?

Create or use an existing plist file in the application. In the plist file, add a new key of String named fontName.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>UICTFontTextStyleBody</key>
	<number>15</number>
</dict>
</plist>

When using HaapiUIKitApplicationBuilder, the plist file name needs to be provided. For example, if the plist file is named: "MyCustom.plist". As explained above in the AppDelegate when using HaapiUIKitApplicationBuilder, a new method needs to be invoked.

HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // It referes to MyCustom.plist. 
.build()

Now every UI component that uses UICTFontTextStyleBody is affected by this change.

Override TextAppearance.Body

TextAppearance.Body is a key that represents a text appearance that uses UICTFontTextStyleBody and natural text alignment (source). This key is used by some UI component such as ActionableButton.Primary.

How to change the text appearance (italic) for ActionableButton.Primary without affecting the other UI component?

Create or use an existing plist file in the application. In the plist file, add a dictionary that fits the requirements for a TextAppearance.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>TextAppearance.MyCustomBody</key>
	<dict>
		<key>fontSymbolicTrait</key>
		<string>traitItalic</string>
	</dict>
</dict>
</plist>

In the same plist file, add a dictionary that fits the requirements for ActionableButton.Primary.

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>TextAppearance.MyCustomBody</key>
	<dict>
		<key>fontSymbolicTrait</key>
		<string>traitItalic</string>
	</dict>
  <key>ActionableButton.Primary</key>
	<dict>
		<key>textAppearance</key>
		<string>TextAppearance.Body</string>
	</dict>
</dict>
</plist>

When using HaapiUIKitApplicationBuilder, the plist file name needs to be provided. For example, if the plist file is named: "MyCustom.plist". As explained above in the AppDelegate when using HaapiUIKitApplicationBuilder, a new method needs to be invoked.

HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // It referes to MyCustom.plist. 
.build()

Now a component that uses ActionableButton.Primary style will only be affected by this change. The change only affects the textAppearance. As highlighted above, there is no need to mention the other keys because the other keys/values are taken from the initial ActionableButton.Primary definition from IdsvrHaapiUIKit.

Define another color in a style definition

textColorName is a key that exists in many style definitions. For example. this key is used in ActionableButton.Primary.

How to define a textColorName for ActionableButton.Primary ?

In the application Asset catalog, define a new set of colors that is named: "pastel_color".

Create or use an existing plist file in the application. In the plist file, add a dictionary that fits the requirements for a TextAppearance.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>ActionableButton.Primary</key>
	<dict>
		<key>textColorName</key>
		<string>pastel_color</string>
	</dict>
</dict>
</plist>

When using HaapiUIKitApplicationBuilder, the plist file name needs to be provided. For example, if the plist file is named: "MyCustom.plist". As explained above in the AppDelegate when using HaapiUIKitApplicationBuilder, a new method needs to be invoked.

HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // It referes to MyCustom.plist. 
.build()

Now a component that uses ActionableButton.Primary style will only be affected by this change. The change only affects the textColorName. As highlighted above, there is no need to mention the other keys because the other keys/values are taken from the initial ActionableButton.Primary definition from IdsvrHaapiUIKit.