Troubleshooting
Frequently asked questions (FAQ)
Colors
Q: I changed a color, but it was not applied
Go through the checklist:
- Is the theme set before
getChat()?chatCenterSDK.theme = myTheme
let chatController = try chatCenterSDK.getChat() - Correct token? Check the semantics in Color palette. For example,
linkandlinkLightare two different tokens for accent elements. - Is a component overriding the token? If
components.navigationBarStyle.titleTextStyle.coloris set explicitly, thetypography.heading1token has no effect on it. - Is the dark theme set separately?
colors.link = .redin the light theme does not affectdarkTheme. applyvsbuild? Changing a component in a Flow viaapplymay affect all screens. Usebuildfor targeted overrides (see Styles → Typical mistakes).- Is the theme recreated before every open? Create
ChatThemeonce at SDK initialization — not before everygetChat()call.
Fonts
Q: I changed typography.body, but the font in bubbles did not change
The text in chat bubbles uses the typography.message token, not body. The default is .systemFont(ofSize: 14).
typography.message = .systemFont(ofSize: 15, weight: .regular)
Q: A custom font is not applied to the navigation bar title
The navigation bar title is controlled through NavigationBarStyle, not through the ChatTypography.title token:
theme.components.navigationBarStyle.titleTextStyle.font = myFont
theme.components.navigationBarStyle.titleTextStyle.color = .white
Components
Q: Changing a component in one Flow affects all screens
Components in ChatComponents are reference types. Mutating through apply modifies the shared object that other Flows also use. To override a component locally, create a new instance via build:
// Changes globally
theme.flows.chatFlow.apply {
$0.inputViewStyle.sendButtonStyle.image = myImage
}
// Targeted override
let customInput = ChatInputStyle.build(with: theme.components) {
$0.sendButtonStyle.image = myImage
}
theme.flows.chatFlow.inputViewStyle = customInput
Q: How do I change the background color of message bubbles?
Set incoming (from the operator) and outgoing (from the client) message bubbles separately:
theme.flows.chatFlow.incomeMessages.bubbleTintColor = .systemBlue
theme.flows.chatFlow.outcomeMessages.bubbleTintColor = .systemGreen
Dark theme
Q: The dark theme does not apply when userInterfaceStyle changes
Make sure that:
darkThemeis set explicitly:chatCenterSDK.darkTheme = darkTheme- The theme is set before
getChat(), or after changing the dark theme the chat is closed and reopened viagetChat()
Q: Some elements do not change color in the dark theme
Some colors (link, linkLight, positive, warning) are the same for light and dark themes by default. For different values, create a separate ChatColors for the dark theme and assign it through darkTheme.
Icons and images
Q: The SF Symbol icon is too small / too large
Use the constructor with an explicit size:
images.attachButtonImage = ChatImage(system: "plus.circle", size: 24, tintColor: .systemBlue)
Edge cases
Q: I set a transparent color — the text disappeared
ChatColors does not check colors for transparency. If you set .clear, the element becomes invisible without an error.
// Text will be invisible
colors.main = .clear
// Semi-transparency
colors.main = .label.withAlphaComponent(0.8)
Q: I changed theme while the chat was already open — the UI did not update
ChatTheme is read when the chat is opened. Changing chatCenterSDK.theme after getChat() does not update components that are already on screen.
Option 1 — reopen the chat (most reliable):
chatCenterSDK.theme = newTheme
do {
let chatController = try chatCenterSDK.getChat() // open again
navigationController?.pushViewController(chatController, animated: true)
} catch {
print("Failed to reopen chat: \(error)")
}
Option 2 — dynamic colors (update automatically on Light / Dark switch):
colors.main = UIColor { trait in
trait.userInterfaceStyle == .dark ? .white : .black
}
Configuration errors
Q: The icon is not showing — how do I diagnose this?
ChatImage(named:) does not throw an error if the asset is not found — the icon simply does not appear (an empty UIImage() is substituted internally). Make sure the asset name and bundle are correct:
// Custom icon from the application bundle
images.sendButtonImage = ChatImage(named: "my_icon", bundle: .main, tintColor: .white)
// Or an SF Symbol (always available, no asset required)
images.sendButtonImage = ChatImage(system: "paperplane.fill", tintColor: .white)
To browse available SF Symbols, use the SF Symbols app (developer.apple.com/sf-symbols).
Q: A custom font is not loading — how do I verify?
The font must be registered in Info.plist under the UIAppFonts key and used by its PostScript name:
// Diagnostics: print all registered PostScript names
for family in UIFont.familyNames.sorted() {
for name in UIFont.fontNames(forFamilyName: family) {
print(name) // ← look for "YourFont-Regular" in the output
}
}
// Always with a fallback
typography.message = UIFont(name: "YourFont-Regular", size: 15)
?? .systemFont(ofSize: 15)
UIFont(name:size:) returns nil without an error if the font is not found — the app does not crash, but the system font is used instead.
Debugging
Q: How do I verify that the theme has been applied?
- Breakpoint in the debugger — set a breakpoint after
chatCenterSDK.theme = myThemeand inspect the object's properties - Xcode View Hierarchy (
Debug → View Hierarchy) — select the element you need; color and font are visible in the inspector on the right - Logging — make sure the code runs in the expected order:
let theme = ChatTheme(colors: colors)
print("Theme ready, link color: \(colors.link)")
chatCenterSDK.theme = theme
let chatController = try chatCenterSDK.getChat()
Did not find an answer?
- API Reference — full list of classes and properties
- Figma UIKit — visual representation of components
- Demo application →
MainViewController+Custom.swift— up-to-date working examples