Cheetah CES Docs Portal

Corporate Site

Getting Started
At a Glance: Using the Cheetah Loyalty Kits
Using Sample Application
UI Customization
iOS Kit Reference
Swift SDK Reference

UI Customization

Customizations of the UI may be desired to establish a certain identity of an app. There are two ways to go about UI Customization:

Theme Manager

The Cheetah Digital UI Kit contains a class called ThemeManager, this class is responsible for applying the Theme related to colors and appearances of the texts inside the app.

Color Theme

To create a color theme for an app, create a struct that conforms to ColorTheme Protocol. Conformimg to this protocol will require the struct to provide the following properties:

  • primaryColor
  • secondaryColor

Additionally there are properties that already have a default value but can be replace by a custom value as needed:

  • textColor
  • textInputColor
  • primaryVariantColor
  • errorColor
  • barItemColor
  • disabledButtonColor
  • highlightedButtonColor
public struct CheetahColorTheme: ColorTheme {

    public let primaryColor = UIColor(hex: "B1E4E3")

    public let secondaryColor = UIColor(hex: "F4364C")


To apply the created theme call the applyColor(theme: ColorTheme) method of the singleton instance of the ThemeManager and make sure that the window that the app uses is an instance of CheetahAppWindow. This setup is preferably call in the app delegate of the application.

func setupTheme() {
    ThemeManager.shared.applyColor(theme: CheetahColorTheme())
    window = CheetahAppWindow(frame: UIScreen.main.bounds)

Text Appearance

TextAppearance protocol is used for modifying the appearances of the texts inside the other parts of the Cheetah Digital SDK without subclassing them.To do this create a struct that conforms to TextTheme and provide the necessary structs that conform to TextAppearance.

public struct MyLargeTitle: TextAppearance {

    public var fontName: String = "Helvetica"

    public var textColor: UIColor = .blue

    public var textStyle: UIFont.TextStyle? = .largeTitle

    public var fontSize: CGFloat?


There are 2 ways on providing the size of a text appearance which will be either providing values on the textStyle or fontSize property in which the former will be always prioritized over the latter if both properties have values.

These are the following elements that support setting of text appearance:

  • UILabel
  • UIButton
  • UITextField
  • UITextView
  • UITextViewCell
  • UIBarItem
  • UINavigationBar

The sample code below is an example of creating a struct that conforms to TextTheme protocol and provides the necessary values to its properties.

public struct CheetahTextTheme: TextTheme {

    public var largeTitle: TextAppearance = CheetahLargeTitle()

    public var title1: TextAppearance = CheetahTitle1()

    public var title2: TextAppearance = CheetahTitle2()

    public var title3: TextAppearance = CheetahTitle3()

    public var headline: TextAppearance = CheetahHeadline()

    public var subheadline: TextAppearance = CheetahSubheadline()

    public var body: TextAppearance = CheetahBody()

    public var callout: TextAppearance = CheetahCallout()

    public var footnote: TextAppearance = CheetahFootnote()

    public var caption1: TextAppearance = CheetahCaption1()

    public var caption2: TextAppearance = CheetahCaption2()

    public var alertButton: TextAppearance = CheetahAlertButtonTextAppearance()

    public var textView: TextAppearance = CheetahTextViewTextAppearance()

    public var textField: TextAppearance = CheetahTextFieldTextAppearance()

    public var normalButton: TextAppearance = CheetahNormalButtonTextAppearance()

    public var disabledButton: TextAppearance = CheetahDisabledButtonTextAppearance()

    public var highlightedButton: TextAppearance = CheetahHighlightedButtonTextAppearance()

To change the text appearance of texts on other Cheetah Digital Kits like Challenges Kit, simply change the text property of the shared instance of the ThemeManager.

func setupTheme() {
    ThemeManager.shared.applyColor(theme: CheetahColorTheme())
    ThemeManager.shared.text = CheetahTextTheme()
    window = CheetahAppWindow(frame: UIScreen.main.bounds)

For texts that are not handled by the Theme Manager it is advisable to use the setTextAppearance(_ textAppearance: TextAppearance) or setTextStyle(_ textStyle: ThemeManager.TextStyle) method of the views that that are supported for easier tracking of styles that are applied. This is also advisable because these method also allows easier styling of text per state of a button.


Layout Customization via Nib/Storyboard

Changing Layout of a View Controller

Customizing the UI layout of a certain screen can be done in two ways. One is creating a subclass of a view controller with a corresponding nib. The other is to create a nib with the name of the class that will be used. For example, the Detail View Controller of the Cheetah Digital UI Kit will be used as the screen that will be modified indicated in the steps below:

Subclassing a view controller

  1. Create a view controller and provide a nib file.
  2. Import CheetahDigitalUI and make the class as the subclass of the desired view controller. For this example DetailViewController

      import CheetahDigitalUI
      class AppDetailViewController: DetailViewController {
          // Provide customization as necessary
  3. Connect the required IBOutlets.

Note: It is recommended that the file name of the swift class is the same with the file name of the nib to avoid providing the nibName in the init of the class.
Due to a bug in .xcframeworks where the IBOutlets of the superclass doesn’t appear in the nib, It is needed to override the IBOutlets in the subclass. Doing this will make the IBOutlets of the superclass in the nib appear enabling connection it to the needed views. And after, delete the overridden IBOutlets.

Creating a nib with the same filename inside the Cheetah Digital UI SDK

  1. Create a nib and named it with the same file name of the nib in the UI SDK.
  2. Change the custom class in the Identity Inspector
  3. Connect the outlets to the views.

Note: Due to a bug in .xcframeworks where the IBOutlets of the superclass doesn’t appear in the nib, it is needed to override the IBOutlets in the subclass. Doing this will make the IBOutlets of the superclass in the nib appear enabling connection it to the needed views. Final step will be to delete the created temporary class.

Changing Layout of a Cell

Subclassing a cell

For creating a custom cell that will be use in a Reward list.

  1. Create a nib for the UICollectionViewCell.
  2. Create a class for the created nib on step 1.

     class RewardListCollectionViewCell: UICollectionViewCell {
         @IBOutlet weak var imageView: UIImageView!
         @IBOutlet weak var titleLabel: UILabel!
         @IBOutlet weak var subtitleLabel: UILabel!
         @IBOutlet weak var expirationLabel: UILabel!
         @IBOutlet weak var dividerView: UIView!
         override func awakeFromNib() {
             dividerView.backgroundColor = .primary
             titleLabel.setTextStyle(.body, alignment: .natural)
             subtitleLabel.setTextStyle(.subheadline, alignment: .natural)
             expirationLabel.setTextStyle(.caption1, alignment: .natural)
  3. Override the registerComponents() and collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell methods of the list controller that will use the created cell, in this example RewardListController.

     class RewardListController: ListCollectionController<Reward> {
         override func registerComponents() {
                                     forCellWithReuseIdentifier: RewardListCollectionViewCell.nibName())
             API Call
             Other list controller methods
         override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
             let reuseIdentifier = RewardListCollectionViewCell.nibName()
             let dequeuedCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
                                                                 for: indexPath)
             guard let cell = dequeuedCell as? RewardListCollectionViewCell else {
                 return dequeuedCell
                 Cell Customization
             return cell

Creating a cell with the same filename inside the Cheetah Digital UI SDK

The steps for changing the layout of the default cells like ListItemCell is identical to the Creating a nib with the same filename inside the Cheetah Digital UI SDK on changing the layout of a view controller.

Next: Kit Reference