The Incode iOS SDK is highly customizable. You can match onboarding flows to your brand and product. This page covers what you can change, including:
- Theme colors and fonts
- Buttons, labels, and other UI elements
- A custom logo
- Runtime theme switching
- Localization, including dynamic and runtime language switching
- V2 theme and UX configuration
Get Started
Most integrations only need colors, fonts, and a logo. Consult the other sections when you have a specific need.
On iOS, all theming is done in Swift at runtime. There is no build-time resource system (such as Android's colors.xml or styles.xml). Instead, you configure a small set of public types and assign them to IncdTheme (V1) or the V2 properties. The V1 (UIKit) screens read from IncdTheme.current (a ThemeConfiguration), while the newer V2 (SwiftUI) screens read from IncdTheme.typography, IncdTheme.colorPalette, IncdTheme.displayMode, and IncdTheme.components. A single JSON blob passed to IncdTheme.loadJsonTheme(_:) populates both systems. This page documents both.
| Task | Section |
|---|---|
| Recolor the SDK and apply your fonts | Customize Theme Colors and Fonts |
| Display your logo | Add a Custom Logo |
| Change button shape, size, color, and style | Customize Buttons |
| Restyle labels, the selfie background, and other elements | Customize Other UI Elements |
| Swap the theme at runtime based on user preference | Configure Runtime Styles |
| Change any on-screen text, particularly for translation | Localize Display Text |
| Theme the V2 (SwiftUI) modules | Configure V2 Theme and UX |
Customize Theme Colors and Fonts
The V1 (UIKit) screens read colors, fonts, buttons, and labels from IncdTheme.current, a ThemeConfiguration. To customize them, copy the current theme, change the properties you need, and assign it back before you start onboarding.
Info
Note
Set the theme before you start a flow. Assigning IncdTheme.current (or any of the V2 properties) takes effect on screens presented afterward.
Colors
ThemeConfiguration.colors is a ColorsConfiguration with the following properties:
| Property | Purpose |
|---|---|
primary |
Primary color for all modules. |
accent |
Accent color for all modules. |
background |
Background color for all modules. |
secondaryBackground |
Secondary background, used when a view sits on top of the background. |
success |
Success color. |
error |
Error or destructive color. |
warning |
Warning color. |
cancel |
Color used for the cancel (X) button. |
cancelDark |
Cancel (X) button color on dark backgrounds, such as during a Video Selfie. |
disabled |
Color for disabled controls. |
primaryDark |
Primary color for dark backgrounds. |
import IncdOnboarding
import UIKit
var theme = IncdTheme.current
theme.colors.primary = UIColor(red: 0.12, green: 0.16, blue: 0.24, alpha: 1)
theme.colors.accent = UIColor(red: 0.0, green: 0.42, blue: 1.0, alpha: 1)
theme.colors.background = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0)
theme.colors.success = UIColor(red: 0.05, green: 0.84, blue: 0.64, alpha: 1)
theme.colors.error = UIColor(red: 1.0, green: 0.36, blue: 0.44, alpha: 1)
theme.colors.warning = UIColor(red: 0.95, green: 0.67, blue: 0.24, alpha: 1)
IncdTheme.current = theme
Fonts
ThemeConfiguration.fonts is a FontsConfiguration. Construct one with the roles you want to override; any role you omit keeps its default.
var theme = IncdTheme.current
theme.fonts = FontsConfiguration(
title: UIFont(name: "YourFont-Bold", size: 24),
subtitle: UIFont(name: "YourFont-Medium", size: 18),
body: UIFont(name: "YourFont-Regular", size: 16),
buttonBig: UIFont(name: "YourFont-Bold", size: 18)
)
IncdTheme.current = theme
FontsConfiguration exposes the following roles:
titlebigTitlehugeTitlesubtitleboldedSubtitlesmallSubtitlesmallBoldedSubtitleinfobodyboldedBodybuttonBigbuttonMediumbuttonSmalltextFieldBigtextFieldMediumfeedbackSmallfeedbackBig
Add a Custom Logo
Show a custom logo at the top of supported screens by setting IncdTheme.logo. It is a UIImage?. If you do not set it, the SDK uses the default Incode logo.
IncdTheme.logo = UIImage(named: "my_logo")
The Video Selfie module lets you show a custom logo just for its own screens. Set it on the module's VideoSelfieConfiguration before adding the module to your flow:
let config = VideoSelfieConfiguration()
config.setLogo(UIImage(named: "my_video_selfie_logo"))
flowConfig.addVideoSelfie(videoSelfieConfiguration: config)
The Video Selfie logo applies only to that module's capture screens. All other supported screens use the generic IncdTheme.logo. See Video Selfie for the full module configuration.
Customize Buttons
ThemeConfiguration.buttons is a ButtonsConfiguration with one ButtonConfiguration per button role: primary, secondary, text, help, and chooser.
Each ButtonConfiguration has:
states: per-state styling fornormal,highlighted, anddisabled, each aButtonThemedState.bigandmedium: size variants, each aButtonSizeVariant.
A ButtonThemedState exposes:
backgroundColorborderColorborderWidthcornerRadiustextColoralphashadowColorshadowOffsetshadowOpacityshadowRadiusiconImageName(optional)iconTintColor(optional)iconPosition(optional)iconPadding(optional)
A ButtonSizeVariant exposes height, minWidth, contentInsets, and kerning.
var theme = IncdTheme.current
// Primary button: normal state
theme.buttons.primary.states.normal.backgroundColor = UIColor(red: 0.0, green: 0.42, blue: 1.0, alpha: 1)
theme.buttons.primary.states.normal.textColor = .white
theme.buttons.primary.states.normal.cornerRadius = 12
theme.buttons.primary.states.normal.borderWidth = 0
// Primary button: disabled state
theme.buttons.primary.states.disabled.backgroundColor = UIColor(white: 0.9, alpha: 1)
theme.buttons.primary.states.disabled.textColor = UIColor(white: 0.6, alpha: 1)
// Primary button: big size variant
theme.buttons.primary.big.height = 64
theme.buttons.primary.big.minWidth = 200
// Secondary button
theme.buttons.secondary.states.normal.backgroundColor = .white
theme.buttons.secondary.states.normal.borderColor = UIColor(red: 0.12, green: 0.16, blue: 0.24, alpha: 1)
theme.buttons.secondary.states.normal.borderWidth = 1
theme.buttons.secondary.states.normal.cornerRadius = 12
IncdTheme.current = theme
Customize Other UI Elements
Colors, fonts, and buttons cover most use cases. If you need more control, the theme exposes label styling and per-component configuration.
Labels
ThemeConfiguration.labels is a LabelsConfiguration with one LabelConfiguration per text role: title, secondaryTitle, subtitle, secondarySubtitle, smallSubtitle, info, secondaryInfo, body, secondaryBody, and code. Each LabelConfiguration exposes textColor, textAlignment, and kerning.
var theme = IncdTheme.current
theme.labels.title.textColor = UIColor(red: 0.12, green: 0.16, blue: 0.24, alpha: 1)
theme.labels.body.textColor = UIColor(white: 0.39, alpha: 1)
theme.labels.info.textAlignment = .center
IncdTheme.current = theme
Selfie and Video Selfie
ThemeConfiguration.customComponents groups per-component styling. Two components are commonly customized:
The Selfie camera background is white by default, which helps in low-light conditions. Change it with
SelfieThemeConfiguration:var theme = IncdTheme.current theme.customComponents.selfie = SelfieThemeConfiguration(background: .white) IncdTheme.current = themeThe Video Selfie overlay and progress bar are configured with
VideoSelfieThemeConfiguration:var theme = IncdTheme.current theme.customComponents.videoSelfie = VideoSelfieThemeConfiguration( overlayColor: .black, overlayAlpha: 0.44, progressBarColor: UIColor.white.withAlphaComponent(0.5), progressBarSelectedColor: .white ) IncdTheme.current = theme
Other custom components
ThemeConfiguration.customComponents also exposes cameraFeedback, idCaptureHelp, idSideLabel, separator, signature, idAutocaptureCountdownConfiguration, and idCaptureFrame. Assign a configured instance of each type to change the matching component. For their individual properties, see API Reference.
Configure Runtime Styles
Because the theme is plain Swift state, you can change it at runtime: for example, to switch styles based on a user's preference. Assign a new value to IncdTheme.current (or to the V2 properties) at any point before the next screen is presented.
func applyHighContrastTheme() {
var theme = IncdTheme.current
theme.colors.primary = .black
theme.colors.accent = .black
theme.colors.background = .white
IncdTheme.current = theme
}
To load a full theme from JSON at runtime, use IncdTheme.loadJsonTheme(_:). See Configure V2 Theme and UX for the JSON format.
let jsonString = "<THEME_JSON_STRING>"
IncdTheme.loadJsonTheme(jsonString)
To reset everything back to Incode's defaults, call:
IncdTheme.loadDefaultTheme()
Localize Display Text
There are three ways to change the text the SDK displays:
- Override the bundled strings at build time
- Replace strings programmatically with dynamic localization
- Switch the SDK language at runtime
The SDK ships default text for five locales: German, English, Spanish, Hebrew, and Portuguese (de, en, es, he, pt).
String keys follow a dotted namespace, for example incdOnboarding.global.button.continue, incdOnboarding.global.button.cancel, and incdOnboarding.global.dialog.ok.
Override Bundled Strings
Point the SDK at your own .strings resources. Set the bundle that contains your Localizable.strings, and optionally a custom file name (without the .strings extension):
IncdLocalization.localizationBundle = Bundle.main
IncdLocalization.localizationStringsFile = "IncodeStrings" // uses IncodeStrings.strings
If you set neither, the SDK reads Localizable.strings from the main bundle, then falls back to its own bundled strings.
Dynamic Localization
Override strings programmatically by assigning a dictionary of key/value pairs to IncdLocalization.current. Values in this dictionary take priority over the bundled localization.
IncdLocalization.current = [
"incdOnboarding.global.button.continue": "Proceed",
"incdOnboarding.global.dialog.ok": "Got it"
]
By default, keys not present in IncdLocalization.current fall back to the bundled localization. You can disable that fallback, though this is recommended only for testing:
IncdLocalization.disableFallback = true
Runtime Localization
Change the SDK language at runtime by setting the preferred language. English is used if the requested language is not bundled.
IncdLocalization.localizationLanguage = "pt"
IncdOnboardingManager.localizationLanguage is deprecated and forwards to IncdLocalization.localizationLanguage. Use IncdLocalization.localizationLanguage directly.
Configure V2 Theme and UX
The V2 (SwiftUI) screens are themed separately from the V1 configuration described above. You configure them with JSON: a theme JSON passed to IncdTheme.loadJsonTheme(_:), and a UX JSON passed to IncdUXConfig.loadUXConfig(_:).
Theme Configuration via JSON
The theme JSON supports displayMode, typography, colorPalette, and components. On iOS, font families are nested under an ios key.
View an example theme JSON
let json = """
{
"displayMode": "light",
"typography": {
"family": {
"text": {
"ios": {
"regular": "DMSans-Regular",
"medium": "DMSans-Medium",
"bold": "DMSans-Bold"
}
},
"display": {
"ios": {
"extraBold": "DMSans-ExtraBold"
}
}
},
"letterSpacing": {
"none": 0,
"medium": -0.5,
"large": -1.0,
"extraLarge": -1.5
}
},
"colorPalette": {
"neutralLight": "#ffffff",
"neutralDark": "#000000",
"brand50": "#e5f0ff",
"brand200": "#99c3ff",
"brand300": "#66a6ff",
"brand400": "#3388ff",
"brand500": "#006aff",
"brand600": "#0055cc",
"brand900": "#21273b",
"gray50": "#FCFCFD",
"gray100": "#EBECEF",
"gray200": "#C6C8D2",
"gray300": "#A3A8B8",
"gray500": "#60667C",
"gray700": "#3A3E4B",
"gray800": "#262831",
"gray900": "#14151A",
"gray1000": "#000000",
"brandSecondary50": "#F2E2FE",
"brandSecondary500": "#820AD1",
"negative50": "#FFF0F0",
"negative400": "#FF5A5F",
"negative500": "#E71111",
"negative950": "#240001",
"warning50": "#FFF7EB",
"warning400": "#FFB647",
"warning500": "#FF9900",
"warning950": "#523100",
"positive50": "#E4FBF0",
"positive400": "#45B380",
"positive500": "#189F60",
"positive950": "#0C5030",
"focus400": "#0099FF",
"focus500": "#006AFF"
},
"components": {
"buttons": [
{
"style": "primary",
"surface": {
"default": ["#000000", "#E8E8E8"],
"hover": "#04FF5C",
"pressed": "#00B540",
"disabled": ["#EBECEF", "#000000"]
},
"text": {
"default": ["#FFFFFF", "#000000"],
"disabled": ["#959595", "#666666"]
},
"border": {
"color": {
"default": "#00D149"
},
"width": 0,
"radius": 15
}
}
]
}
}
"""
Apply it to the SDK:
IncdTheme.loadJsonTheme(json)
Note:
displayModecan be"light","dark", or"system". If not set, the default is"light".- Font families are nested under
ios. The font names must resolve to fonts available to your app (bundled and declared, or system fonts). - Color tokens use hex strings. Both
#RRGGBBand#AARRGGBB(with a leading alpha byte) are accepted. - A
surface,text, orbordercolor can be either a single hex string or a two-element array[light, dark]for per-appearance colors. - Button
stylecan be"primary"or"secondary". - All properties are optional; anything you omit keeps its default.
Info
Note
IncdTheme.loadJsonTheme(_:) reads the same JSON to populate both the V1 (IncdTheme.current) and V2 (typography, colorPalette, displayMode, components) state, so you can theme both systems from one blob.
UX Configuration via JSON
UX configuration controls layout and chrome for the V2 screens. Pass a JSON string to IncdUXConfig.loadUXConfig(_:).
let jsonString = """
{
"showFooter": true,
"closeButtonPosition": "topLeft",
"helpButtonPosition": "topRight",
"headerAlignment": "center",
"realtimeFeedbackMessageUIFlavor": "standard"
}
"""
IncdUXConfig.loadUXConfig(jsonString)
View available properties and their possible values
| Property | Type | Values | Default | Description |
|---|---|---|---|---|
showFooter |
Boolean | true or false |
true |
Controls whether the SDK shows the footer. |
closeButtonPosition |
String | topRight, topLeft |
topRight |
Position of the close button. |
helpButtonPosition |
String | topRight, topLeft, bottomRight |
bottomRight |
Position of the help button. |
realtimeFeedbackMessageUIFlavor |
String | standard, minimal |
standard |
Visual flavor of real-time feedback messages. |
headerAlignment |
String | start, center, end |
center |
Alignment of the header. |