Быстрый старт
Скопируйте пример целиком и адаптируйте под ваш бренд.
Минимальный пример
Самый быстрый способ применить фирменный цвет:
let colors = ChatColors()
colors.link = UIColor(named: "BrandColor") ?? .systemBlue
chatCenterSDK.theme = ChatTheme(colors: colors)
Полный пример с брендингом
Шаг 1 — Цвета
let colors = ChatColors()
// Основной текст и фон
colors.main = UIColor(named: "TextPrimary") ?? .label
colors.secondary = UIColor(named: "TextSecondary") ?? .secondaryLabel
colors.background = UIColor(named: "BackgroundPrimary") ?? .systemBackground
// Акцентный (фирменный) цвет
colors.link = UIColor(named: "BrandColor") ?? .systemBlue
colors.positive = UIColor(named: "BrandColor") ?? .systemBlue
// Ошибки и предупреждения (оставьте по умолчанию или задайте)
// colors.error = .systemRed
// colors.warning = .systemOrange
Шаг 2 — Шрифты
let typography = ChatTypography()
// Текст в пузырях сообщений
typography.message = .systemFont(ofSize: 15, weight: .regular)
// Кастомный шрифт (если зарегистрирован в приложении):
// typography.message = UIFont(name: "YourFont-Regular", size: 15) ?? .systemFont(ofSize: 15)
// Заголовок навигационной панели
typography.title = .systemFont(ofSize: 17, weight: .semibold)
Шаг 3 — Создать тему
let theme = ChatTheme(colors: colors, typography: typography)
Шаг 4 — Применить
getChat()Контроллер чата читает значения темы при создании. Изменения темы после getChat() не применятся к уже открытому экрану — чтобы применить новую тему, вызовите getChat() повторно.
// Полную обработку ошибок getChat() см. в getting-started/open_chat.md
func openChat() throws(ChatCenterUIError) {
chatCenterSDK.theme = theme
let chatController = try chatCenterSDK.getChat()
navigationController?.pushViewController(chatController, animated: true)
}
Шаг 5 — Тёмная тема (опционально)
let darkColors = ChatColors()
darkColors.main = .white
darkColors.secondary = UIColor(white: 0.7, alpha: 1)
darkColors.background = UIColor(named: "BackgroundDark") ?? .black
darkColors.link = UIColor(named: "BrandColorDark") ?? .systemBlue
let darkTheme = ChatTheme(colors: darkColors, typography: typography)
chatCenterSDK.darkTheme = darkTheme
Если darkTheme не задан, SDK использует светлую тему в обоих режимах.
Независимые светлая и тёмная темы
Не передавайте один и тот же ChatComponents в две темы. ChatComponents — класс, стили (navigationBarStyle, inputViewStyle) хранятся прямо на нём, и изменение объекта затронет обе темы:
// Антипаттерн: общий ChatComponents
let components = ChatComponents()
let lightTheme = ChatTheme(components: components)
let darkTheme = ChatTheme(components: components)
components.navigationBarStyle.backgroundColor = .white
// затрагивает обе темы
Правильно — отдельная тема из своих цветов:
let lightTheme = ChatTheme(colors: lightColors, typography: typography)
let darkTheme = ChatTheme(colors: darkColors, typography: typography)
Каждый вызов ChatTheme(colors:images:typography:) создаёт внутри новый ChatComponents.
Если нужна детальная настройка компонентов под каждую тему, создавайте отдельные ChatComponents:
let lightComponents = ChatComponents(colors: lightColors, typography: typography)
lightComponents.navigationBarStyle.backgroundColor = .white
let darkComponents = ChatComponents(colors: darkColors, typography: typography)
darkComponents.navigationBarStyle.backgroundColor = UIColor(white: 0.15, alpha: 1)
chatCenterSDK.theme = ChatTheme(components: lightComponents)
chatCenterSDK.darkTheme = ChatTheme(components: darkComponents)
ChatComponentsПараметр images: в ChatComponents(...) и ChatTheme(...) имеет значение по умолчанию (ChatImages()). Если вы настроили иконки в отдельном объекте ChatImages, передайте его в инициализатор явно, иначе значения сбросятся к дефолтным SF Symbol'ам SDK.
Полный код одним блоком
import ChatCenterUI
func configureChatTheme() {
// MARK: - Светлая тема
let colors = ChatColors()
colors.main = UIColor(named: "TextPrimary") ?? .label
colors.secondary = UIColor(named: "TextSecondary") ?? .secondaryLabel
colors.background = UIColor(named: "BackgroundPrimary") ?? .systemBackground
colors.link = UIColor(named: "BrandColor") ?? .systemBlue
colors.positive = UIColor(named: "BrandColor") ?? .systemBlue
let typography = ChatTypography()
typography.message = .systemFont(ofSize: 15, weight: .regular)
typography.title = .systemFont(ofSize: 17, weight: .semibold)
let theme = ChatTheme(colors: colors, typography: typography)
// MARK: - Тёмная тема
let darkColors = ChatColors()
darkColors.main = UIColor(named: "TextPrimaryDark") ?? .white
darkColors.secondary = UIColor(named: "TextSecondaryDark") ?? .lightGray
darkColors.background = UIColor(named: "BackgroundDark") ?? UIColor(white: 0.1, alpha: 1)
darkColors.link = UIColor(named: "BrandColorDark") ?? .systemBlue
let darkTheme = ChatTheme(colors: darkColors, typography: typography)
// MARK: - Применение
chatCenterSDK.theme = theme
chatCenterSDK.darkTheme = darkTheme
}
Вызовите configureChatTheme() при инициализации SDK, до открытия чата.
theme → darkThemeПрисваивание chatCenterSDK.theme молча перезаписывает текущий darkTheme ссылкой на ту же тему. Всегда задавайте theme до darkTheme. При динамической смене обеих тем переустанавливайте их подряд в том же порядке.
Место вызова в приложении
Задайте тему один раз при инициализации SDK, до первого открытия чата:
// AppDelegate.swift или SceneDelegate.swift
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let sdk = ChatCenterUISDK(providerUid: "your-provider-uid",
appMarker: "your-app-marker",
chatConfig: chatConfig)
sdk.theme = createLightTheme()
sdk.darkTheme = createDarkTheme()
self.chatCenterSDK = sdk
return true
}
Полная инициализация SDK и паттерны передачи экземпляра между экранами описаны в инициализации SDK и SwiftUI-интеграции.
Не пересоздавайте ChatTheme с одинаковыми параметрами перед каждым getChat(). Создайте тему один раз и переиспользуйте; при динамическом переключении присваивайте уже подготовленный объект:
func openChat(with style: AppThemeStyle) throws(ChatCenterUIError) {
chatCenterSDK.theme = themeCache[style]
let chatController = try chatCenterSDK.getChat()
navigationController?.pushViewController(chatController, animated: true)
}
Такой паттерн использует демо-приложение при смене темы из настроек.
Замена иконок
Иконки переопределяются через ChatImages. Передайте объект в ChatTheme вместе с цветами и шрифтами:
let images = ChatImages()
images.sendButtonImage = ChatImage(system: "paperplane.fill", tintColor: .white)
images.attachButtonImage = ChatImage(system: "plus.circle.fill", tintColor: .white)
images.voiceButtonImage = ChatImage(system: "waveform", tintColor: .white)
let theme = ChatTheme(colors: colors, images: images, typography: typography)
Полный список иконок — в разделе Изображения.
Как проверить изменения
Запустите приложение на симуляторе и откройте чат. Для тёмной темы переключите оформление в Settings → Developer → Dark Appearance или нажмите ⌘⇧A в симуляторе.
Рабочий пример со всеми параметрами — в демо-приложении (MainViewController+Custom.swift).
Что дальше
| Задача | Раздел |
|---|---|
| Все доступные токены цветов | Цветовая схема |
| Все токены шрифтов и Figma-маппинг | Типографика |
| Замена иконок | Изображения |
| Детальная настройка кнопок, панелей | Компоненты |
| Точечная настройка одного экрана | Сценарии |
| Что-то не работает | Troubleshooting |
| Не понятны термины | Глоссарий |