---
source_url: https://www.pubnub.com/docs/chat/community-supported/ios/ui-theming
title: UI theming for PubNub Chat Components for iOS
updated_at: 2026-06-17T11:36:46.852Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# UI theming for PubNub Chat Components for iOS

PubNub Chat Components for iOS rely on [UIKit](https://developer.apple.com/documentation/uikit) from Apple - a graphical framework for creating unified app interfaces that defines classes of similar [UIViews](https://developer.apple.com/documentation/uikit/uiview) and [UIControls](https://developer.apple.com/documentation/uikit/uicontrol), like buttons.

UIKit uses the imperative programming model where you must clearly describe each view for the app - what it will consist of and how it will look like. This is done by defining object-oriented view models that are hierarchical structures of views - all of them being ultimately child classes of the root [UIVIew](https://developer.apple.com/documentation/uikit/uiview).

This hierarchical model is also reflected in how PubNub Chat Components for iOS are themed. Each [UI component](https://www.pubnub.com/docs/chat/community-supported/ios/ui-components) has an overarching [component theme](https://github.com/pubnub/chat-components-ios/tree/master/Sources/PubNubChatComponents/Theming) that consists of a list of subthemes defining the detailed theming options for each subelement of a given UI component. For example, `ChannelListComponentTheme`, that provides the overall theme for the [ChannelList](https://www.pubnub.com/docs/chat/community-supported/ios/ui-components#channellist) component, is composed of three subthemes: `CollectionViewComponentTheme`, `BasicComponentTheme`, and `ChannelListCellComponentTheme`. All these subthemes contain their own definitions of how a given subview for the `ChannelList` should look like and what default values it should take.

The overarching `ChannelListComponentTheme` itself is only one of the four main building blocks that provide default theming in PubNub Chat Components for iOS and compose the overall [ThemeTemplate](#theme-template).

## Theme template

[ThemeTemplate](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/ThemeProvider.swift) is a class that provides default appearance and structural configuration for all [UI components](https://www.pubnub.com/docs/chat/community-supported/ios/ui-components) and their subcomponents through these themes:

* `ChannelListComponentTheme`
* `MemberListComponentTheme`
* `MessageListComponentTheme`
* `MessageInputComponentTheme`

`ThemeTemplate` compiles all these high-level UI component themes into a single object (`ObservableObject`):

```swift
public class ThemeTemplate: ObservableObject {
 @Published public var channelListComponent: ChannelListComponentTheme
 @Published public var memberListComponent: MemberListComponentTheme
 @Published public var messageListComponent: MessageListComponentTheme
 @Published public var messageInputComponent: MessageInputComponentTheme
 
 public init(
   channelListComponent: ChannelListComponentTheme = .pubnubDefaultGroupChannelList,
   memberListComponent: MemberListComponentTheme = .pubnubDefaultGroupMemberList,
   messageListComponent: MessageListComponentTheme = .pubnubGroupChat,
   messageInputComponent: MessageInputComponentTheme = .pubnubGroupChat
 ) {
   self.channelListComponent = channelListComponent
   self.memberListComponent = memberListComponent
   self.messageListComponent = messageListComponent
   self.messageInputComponent = messageInputComponent
 }
}
```

`ThemeTemplate` provides the default theming values for all components, like `pubnubDefaultGroupChannelList` for the `ChannelList`. This is done through a wrapper called [themeProvider](https://www.pubnub.com/docs/chat/community-supported/ios/chat-provider#themeprovider) that's a property of a [ChatProvider](https://www.pubnub.com/docs/chat/community-supported/ios/chat-provider) instance.

```swift
open class ComponentThemeProvider {
  public static var shared = ComponentThemeProvider()
  private init() {}
  
  @Published public var template: ThemeTemplate = .init()
}

extension ChatProvider {
  public var themeProvider: ComponentThemeProvider {
    return ComponentThemeProvider.shared
  }
}
```

On initializing a given view model, such as `ChannelList`, Chat Provider applies the default theme for the component (`provider.themeProvider.template.channelListComponent`) passed in the `ThemeTemplate` (`template`):

```swift
  public init(
    provider: ChatProvider<ModelData,ManagedEntities>,
    fetchedEntities: NSFetchedResultsController<ManagedEntities.Member>,
    componentTheme: ChannelListComponentTheme? = nil
  ) {
    self.fetchedEntities = fetchedEntities
    self.componentTheme = componentTheme ?? provider.themeProvider.template.channelListComponent
  
    super.init(provider: provider)
  
    self.layoutShouldContainSupplimentaryViews = fetchedEntities.sectionNameKeyPath != nil
    self.fetchedEntities.delegate = self
  }
```

## Light and dark layouts

PubNub Chat Components for iOS support a single theme for your app. Depending on whether you have the dark or light system-wide appearance settings active on your device, the app automatically adapts a dark or light version of all colors defined in themes for PubNub Chat Components for iOS. This is supported automatically through [Apple's adaptive elements](https://developer.apple.com/documentation/uikit/appearance_customization/supporting_dark_mode_in_your_interface).

Let's look at the example of [BubbleComponentTheme](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/ThemeProvider.swift) that's a nested subclass of the [MessageListComponentTheme](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/MessageListComponentTheme.swift) and is responsible for theming a message bubble.

```swift
public class BubbleComponentTheme: ObservableObject {
  @Published public var alignment: UICollectionViewCell.Alignment
  @Published public var containerType: BubbleContainerType
  @Published public var backgroundColor: UIColor?
  @Published public var tailSize: CGFloat
  @Published public var layoutMargin: UIEdgeInsets
  
  public init(
    alignment: UICollectionViewCell.Alignment = .leading,
    containerType: BubbleContainerType = .tailed,
    backgroundColor: UIColor = .systemBlue,
    tailSize: CGFloat = 5,
    layoutMargin: UIEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
  ) {
    self.alignment = alignment
    self.containerType = containerType
    self.backgroundColor = backgroundColor
    self.tailSize = tailSize
    self.layoutMargin = layoutMargin
  }
}
```

As you can see, it is set to use `systemBlue`, one of [Apple's standard colors](https://developer.apple.com/documentation/uikit/uicolor/standard_colors), for the `backgroundColor` of the message bubble. Depending on whether you have the light or dark mode active, `backgroundColor` will automatically adapt the light and dark version of `systemBlue`.

## Component themes

As already mentioned, PubNub Chat Components for iOS provide [ThemeTemplate](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/ThemeProvider.swift) that's a skeleton class for the four high-level component themes: `ChannelListComponentTheme`, `MemberListComponentTheme`, `MessageListComponentTheme`, and `MessageInputComponentTheme`.

```swift
public class ThemeTemplate: ObservableObject {
  @Published public var channelListComponent: ChannelListComponentTheme
  @Published public var memberListComponent: MemberListComponentTheme
  @Published public var messageListComponent: MessageListComponentTheme
  @Published public var messageInputComponent: MessageInputComponentTheme
  ...
}
```

Each of these high-level themes has a nested structure of its own. They are composed of various subthemes that define all subelements (subviews) of the whole [UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview) for a given component. For example, [MemberListComponentTheme](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/MemberListComponentTheme.swift) is made up of three subthemes - the list itself (`collectionViewTheme`), the header for the UICollectionView (`sectionHeaderLabel`), and the actual member list items (`cellTheme`).

```swift
public class MemberListComponentTheme: ViewControllerComponentTheme {
  @Published public var collectionViewTheme: CollectionViewComponentTheme
  @Published public var sectionHeaderLabel: LabelComponentTheme
  @Published public var cellTheme: MemberListCellComponentTheme
```

Further down the structure, you can see that `MemberListCellComponentTheme`, which defines a single item theme, specifies `backgroundColor`, `highlightColor`, and `selectedColor` for the list item and references `BasicComponentTheme` for further default values.

```swift
public class MemberListCellComponentTheme: CollectionViewCellTheme {
  // Appearance
  @Published public var itemTheme: BasicComponentTheme
  
  public init(
    cellType: CollectionViewCellComponent.Type,
    backgroundColor: UIColor = .clear,
    highlightColor: UIColor = .clear,
    selectedColor: UIColor = .clear,
    itemTheme: BasicComponentTheme = .pubnubGroupMemberList
  ) {
    self.itemTheme = itemTheme
  
    super.init(
      customType: cellType,
      backgroundColor: backgroundColor,
      highlightColor: highlightColor,
      selectedColor: selectedColor
    )
  }
}
```

As you can see, the four major component themes are composed of multiple building blocks that either provide the default values that should be applied for the component theming or reference different subthemes that define these values down the hierarchy. All themes end with the `Theme` suffix and are named after the UI element they refer to, like `NavigationBarTheme` for the NavigationBar UI element.

## Default values and configurable parameters

Default values for all component themes are passed through these group variables:

```swift
public class ThemeTemplate: ObservableObject {
  ...
  public init(
    channelListComponent: ChannelListComponentTheme = .pubnubDefaultGroupChannelList,
    memberListComponent: MemberListComponentTheme = .pubnubDefaultGroupMemberList,
    messageListComponent: MessageListComponentTheme = .pubnubGroupChat,
    messageInputComponent: MessageInputComponentTheme = .pubnubGroupChat
  )
  ...
}
```

Read on to learn what are the default implementations of all high-level component themes and which parameters you can configure to adjust theming to your use case.

### ChannelList

The default implementation is available through `ChannelListComponentTheme.pubnubDefaultGroupChannelList` which is composed of the following values:

```swift
ChannelListComponentTheme(
  controllerType: CollectionViewComponent.self,
  backgroundColor: .clear,
  navigationTitleView: BasicComponentTheme(
    imageView: ImageComponentTheme(
      customType: PubNubAvatarComponentView.self,
      localImage: AppearanceTemplate.Image.avatar,
      diameterSize: 42,
      margin: .init(top: .zero, left: .zero, bottom: .zero, right: 5.0)
    ),
    primaryLabel: LabelComponentTheme(
      customType: PubNubLabelComponentView.self,
      textFont: AppearanceTemplate.Font.title2.bold,
      textColor: AppearanceTemplate.Color.label,
      adjustsFontForContentSizeCategory: true,
      textAlignment: .natural,
      textMargin: .zero
    )
  ),
  collectionViewTheme: CollectionViewComponentTheme(
    viewType: UICollectionView.self,
    layoutType: TableCollectionViewLayout.self,
    headerType: ReusableLabelViewComponent.self,
    footerType: ReusableLabelViewComponent.self,
    backgroundColor: .systemBackground,
    isPrefetchingEnabled: true,
    scrollingBounces: false,
    alwaysBounceVertical: false,
    showsHorizontalScrollIndicator: false,
    keyboardDismissMode: .interactive,
    automaticallyAdjustsScrollIndicatorInsets: true,
    contentInsetAdjustmentBehavior: .always
  ),
  headerLabel: LabelComponentTheme(
    customType: PubNubLabelComponentView.self,
    textFont: AppearanceTemplate.Font.title1.bold,
    textColor: AppearanceTemplate.Color.label,
    adjustsFontForContentSizeCategory: true,
    textAlignment: .natural,
    textMargin: .zero
  ),
  itemTheme: ChannelListCellComponentTheme(
    customType: CollectionViewContainerCellComponent.self,
    viewModelType: ChannelCellViewModel.self,
    backgroundColor: .clear,
    highlightColor: .clear,
    selectedColor: .systemGray4,
    itemTheme: BasicComponentTheme(
      imageView: ImageComponentTheme(
        customType: PubNubAvatarComponentView.self,
        localImage: AppearanceTemplate.Image.avatar,
        diameterSize: 30,
        margin: .init(top: .zero, left: 10.0, bottom: .zero, right: 5.0)
      ),
      primaryLabel: LabelComponentTheme(
        customType: PubNubLabelComponentView.self,
        textFont: AppearanceTemplate.Font.caption1,
        textColor: AppearanceTemplate.Color.label,
        adjustsFontForContentSizeCategory: true,
        textAlignment: .natural,
        textMargin: .zero
      ),
      secondaryLabel: LabelComponentTheme(
        customType: PubNubLabelComponentView.self,
        textFont: AppearanceTemplate.Font.caption2,
        textColor: AppearanceTemplate.Color.secondaryLabel,
        adjustsFontForContentSizeCategory: true,
        textAlignment: .natural,
        textMargin: .zero
      )
    )
  )
)
```

You can configure the `ChannelListComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `controllerType` | `ComponentViewController` | No | Default class type that's used when creating new `UIViewController` instances. |
| `backgroundColor` | `UIColor` | Yes | View Controller’s background color. |
| `navigationTitleView` | `BasicComponentTheme?` | Yes | Theming for `UIView` found on the `UINavigationItem` component. |
| `collectionViewTheme` | `CollectionViewComponentTheme` | Yes | Theming for `UICollectionView` found on the `UIViewController` component. |
| `sectionHeaderLabel` | `LabelComponentTheme` | Yes | Theming for `UILabel` you can attach to the `UICollectionReusableView` section Header-type. |
| `cellTheme` | `MemberListCellComponentTheme` | Yes | Theming for `UICollectionViewCell` found on the `UIViewController` component. |

You can configure the `CollectionViewComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `viewType` | `UICollectionView.Type` | No | Default class type that's used when creating new `UICollectionView` instances. |
| `layoutType` | `CollectionViewLayoutComponent.Type` | No | Default class type that's used when creating new `UICollectionViewLayout` instances. |
| `headerType` | `UICollectionReusableView.Type` | No | Default class type that's used when creating new `UICollectionView` section headers. |
| `footerType` | `UICollectionReusableView.Type` | No | Default class type that's used when creating new `UICollectionView` section footers. |
| `backgroundColor` | `UIColor` | Yes | View background color. |
| `scrollViewTheme` | `ScrollViewComponentTheme` | Yes | Theming for the `UIScrollView` properties of `UICollectionView`. |
| `refreshControlTheme` | `RefreshControlTheme?` | Yes | Theming for the `UIRefreshControl` properties of `UICollectionView`. |
| `prefetchIndexThreshold` | `Int?` | Yes | List index that when scrolled past triggers a remote sync request to fetch additional data to be stored into the local database. |
| `isPrefetchingEnabled` | `Bool` | No | A Boolean value that indicates whether cell and data pre-fetching are enabled. This allows for more efficient pre-fetching, but isn't required. |

You can configure the `ChannelListCellComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `cellType` | `CollectionViewCellComponent.Type` | No | Default class type that's used when creating new `UICollectionViewCell` instances. |
| `backgroundColor` | `UIColor?` | Yes | View's background color. |
| `highlightColor` | `UIColor?` | Yes | View's background color during highlighted state. |
| `selectedColor` | `UIColor?` | Yes | View's background color during selected state. |
| `itemTheme` | `BasicComponentTheme` | Yes | Theming for the sub-views of the channel list cell. |

You can configure the `BasicComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `imageView` | `ImageComponentTheme` | Yes | Theming for the User avatar `UIImageView` |
| `primaryLabel` | `LabelComponentTheme` | Yes | Theming for the primary `UILabelView` that can be displayed on the channel list cell. |
| `secondaryLabel` | `LabelComponentTheme` | Yes | Theming for the secondary `UILabelView` that can be displayed on the channel list cell. |
| `tertiaryLabel` | `LabelComponentTheme` | Yes | Theming for the tertiary `UILabelView` that can be displayed on the channel list cell. |
| `quaternaryLabel` | `LabelComponentTheme` | Yes | Theming for the quaternary `UILabelView` that can be displayed on the channel list cell. |

You can configure the `ImageComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `customType` | `ImageComponentView.Type` | No | Default class type that's used when creating new `UIImageView` instances. |
| `localImage` | `UIImage?` | Yes | Locally sourced `UIImage` you can use as a placeholder while fetching remote images. |
| `cornerRadius` | `CGFloat` | Yes | The radius to use when drawing rounded corners for the layer’s background. |
| `margin` | `UIEdgeInsets` | Yes | The default spacing to use when laying out content in the view. |

You can configure the `LabelComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `textFont` | `UIFont` | Yes | Font of the text. |
| `textColor` | `UIColor` | Yes | Color of the text. |
| `textAlignment` | `NSTextAlignment` | Yes | Technique for aligning the text. |
| `adjustsFontForContentSizeCategory` | `Bool` | Yes | Boolean that determines whether the text's font size is reduced to fit inside the bounds of the `UILabelView`. |

### MemberList

The default implementation is available through `MemberListComponentTheme.pubnubDefaultGroupMemberList` which is composed of the following values:

```swift
MemberListComponentTheme(
  controllerType: CollectionViewComponent.self,
  backgroundColor: .clear,
  navigationTitleView: BasicComponentTheme(
    imageView: ImageComponentTheme(
      customType: PubNubAvatarComponentView.self,
      localImage: AppearanceTemplate.Image.avatar,
      diameterSize: 42,
      margin: .init(top: .zero, left: .zero, bottom: .zero, right: 5.0)
    ),
    primaryLabel: LabelComponentTheme(
      customType: PubNubLabelComponentView.self,
      textFont: AppearanceTemplate.Font.title2.bold,
      textColor: AppearanceTemplate.Color.label,
      adjustsFontForContentSizeCategory: true,
      textAlignment: .natural,
      textMargin: .zero
    )
  ),
  collectionViewTheme: CollectionViewComponentTheme(
    viewType: UICollectionView.self,
    layoutType: TableCollectionViewLayout.self,
    headerType: ReusableLabelViewComponent.self,
    footerType: ReusableLabelViewComponent.self,
    backgroundColor: .systemBackground,
    isPrefetchingEnabled: true,
    scrollingBounces: false,
    alwaysBounceVertical: false,
    showsHorizontalScrollIndicator: false,
    keyboardDismissMode: .interactive,
    automaticallyAdjustsScrollIndicatorInsets: true,
    contentInsetAdjustmentBehavior: .always
  ),
  headerLabel: LabelComponentTheme(
    customType: PubNubLabelComponentView.self,
    textFont: AppearanceTemplate.Font.title1.bold,
    textColor: AppearanceTemplate.Color.label,
    adjustsFontForContentSizeCategory: true,
    textAlignment: .natural,
    textMargin: .zero
  ),
  itemTheme: MemberListCellComponentTheme(
    customType: CollectionViewContainerCellComponent.self,
    viewModelType: MemberCellViewModel.self,
    backgroundColor: .clear,
    highlightColor: .clear,
    selectedColor: .clear,
    itemTheme: BasicComponentTheme(
      imageView: ImageComponentTheme(
        customType: PubNubAvatarComponentView.self,
        localImage: AppearanceTemplate.Image.avatar,
        diameterSize: 30,
        margin: .init(top: .zero, left: 10.0, bottom: .zero, right: 5.0)
      ),
      primaryLabel: LabelComponentTheme(
        customType: PubNubLabelComponentView.self,
        textFont: AppearanceTemplate.Font.caption1,
        textColor: AppearanceTemplate.Color.label,
        adjustsFontForContentSizeCategory: true,
        textAlignment: .natural,
        textMargin: .zero
      ),
      secondaryLabel: LabelComponentTheme(
        customType: PubNubLabelComponentView.self,
        textFont: AppearanceTemplate.Font.caption2,
        textColor: AppearanceTemplate.Color.secondaryLabel,
        adjustsFontForContentSizeCategory: true,
        textAlignment: .natural,
        textMargin: .zero
      )
    )
  )
)
```

You can configure the `MemberListComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `controllerType` | `ComponentViewController` | No | Default class type that's used when creating new `UIViewController` instances. |
| `backgroundColor` | `UIColor` | Yes | View Controller’s background color. |
| `navigationTitleView` | `BasicComponentTheme?` | Yes | Theming for `UIView` found on the `UINavigationItem` component. |
| `collectionViewTheme` | `CollectionViewComponentTheme` | Yes | Theming for `UICollectionView` found on the `UIViewController` component. |
| `sectionHeaderLabel` | `LabelComponentTheme` | Yes | Theming for `UILabel` you can attach to the `UICollectionReusableView` section Header-type. |
| `cellTheme` | `MemberListCellComponentTheme` | Yes | Theming for `UICollectionViewCell` found on the `UIViewController` component. |

You can configure the `CollectionViewComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `viewType` | `UICollectionView.Type` | No | Default class type that's used when creating new `UICollectionView` instances. |
| `layoutType` | `CollectionViewLayoutComponent.Type` | No | Default class type that's used when creating new `UICollectionViewLayout` instances. |
| `headerType` | `UICollectionReusableView.Type` | No | Default class type that's used when creating new `UICollectionView` section headers. |
| `footerType` | `UICollectionReusableView.Type` | No | Default class type that's used when creating new `UICollectionView` section footers. |
| `backgroundColor` | `UIColor` | Yes | View background color. |
| `scrollViewTheme` | `ScrollViewComponentTheme` | Yes | Theming for `UIScrollView` properties of `UICollectionView`. |
| `refreshControlTheme` | `RefreshControlTheme?` | Yes | Theming for `UIRefreshControl` properties of `UICollectionView`. |
| `prefetchIndexThreshold` | `Int?` | Yes | List index that when scrolled past triggers a remote sync request to fetch additional data to be stored into the local database. |
| `isPrefetchingEnabled` | `Bool` | No | A Boolean value that indicates whether cell and data pre-fetching are enabled. This allows for more efficient pre-fetching, but isn't required. |

You can configure the `MemberListCellComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `cellType` | `CollectionViewCellComponent.Type` | No | Default class type that's used when creating new `UICollectionViewCell` instances. |
| `backgroundColor` | `UIColor?` | Yes | View's background color. |
| `highlightColor` | `UIColor?` | Yes | View's background color during highlighted state. |
| `selectedColor` | `UIColor?` | Yes | View's background color during selected state. |
| `itemTheme` | `BasicComponentTheme` | Yes | Theming for the sub-views of the member list cell.. |

You can configure the `BasicComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `imageView` | `ImageComponentTheme` | Yes | Theming for the User avatar `UIImageView` |
| `primaryLabel` | `LabelComponentTheme` | Yes | Theming for the primary `UILabelView` you can display on the member list cell. |
| `secondaryLabel` | `LabelComponentTheme` | Yes | Theming for the secondary `UILabelView` you can display on the member list cell. |
| `tertiaryLabel` | `LabelComponentTheme` | Yes | Theming for the tertiary `UILabelView` you can display on the member list cell. |
| `quaternaryLabel` | `LabelComponentTheme` | Yes | Theming for the quaternary `UILabelView` you can display on the member list cell. |

You can configure the `ImageComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `customType` | `ImageComponentView.Type` | No | Default class type that's used when creating new `UIImageView` instances. |
| `localImage` | `UIImage?` | Yes | Locally sourced `UIImage` you can use as a placeholder while fetching remote images. |
| `cornerRadius` | `CGFloat` | Yes | The radius to use when drawing rounded corners for the layer’s background. |
| `margin` | `UIEdgeInsets` | Yes | The default spacing to use when laying out content in the view. |

You can configure the `LabelComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `textFont` | `UIFont` | Yes | Font of the text. |
| `textColor` | `UIColor` | Yes | Color of the text. |
| `textAlignment` | `NSTextAlignment` | Yes | Technique for aligning the text. |
| `adjustsFontForContentSizeCategory` | `Bool` | Yes | Boolean that determines whether the text's font size is reduced to fit inside the bounds of `UILabelView`. |

### MessageList

The default implementation is available through `MessageInputComponentTheme.pubnubGroupChat` which is composed of the following values:

```swift
MessageListComponentTheme(
  controllerType: CollectionViewComponent.self,
  backgroundColor: .systemBackground,
  messageInputComponent: .pubnubGroupChat,
  collectionViewTheme:  CollectionViewComponentTheme(
    layoutType: ChatLayout.self,
    backgroundColor: .secondarySystemBackground,
    scrollViewTheme: .enabled,
    refreshControlTheme: .init(
      pullToRefreshTitle: .init(string: "Pull to Refresh"),
      pullToRefreshTintColor: nil
    ),
    prefetchIndexThreshold: 35,
    isPrefetchingEnabled: false
  ),
  incomingItemTheme: MessageListCellComponentTheme(
    textMessageContentCellType: MessageListItemCell.self,
    richMessageContentCellTypes: [
      .link: MessageLinkContentCell.self
    ],
    backgroundColor: .clear,
    highlightColor: .clear,
    selectedColor: .clear,
    alignment: .leading,
    maxWidthPercentage: 0.65,
    bubbleContainerTheme: BubbleComponentTheme(
      alignment: .leading,
      containerType: .tailed,
      backgroundColor: .systemBlue,
      tailSize: 5,
      layoutMargin: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
    ),
    contentTextTheme: TextViewComponentTheme(
      customType: UITextView.self,
      backgroundColor: .clear,
      textColor: .black,
      textFont: AppearanceTemplate.Font.body,
      usesStandardTextScaling: false,
      dataDetectorTypes: .all,
      linkTextAttributes: [:],
      isEditable: false,
      isExclusiveTouch: false,
      scrollView: .disabled,
      textContainerInset: .zero
    ),
    contentLinkTheme: LinkViewComponentTheme(
      cacheProvider: InMemoryLinkMetadataCache.shared,
      layoutMargin: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
    ),
    itemTheme: .pubnubGroupChannelList,
    dateFormatter: .messageInline
  ),
  authorItemTheme: nil,
  typingIndicatorCellTheme: AnimatedTypingIndicatorCellTheme(
    cellType: IMessageTypingIndicatorCell.self,
    contentViewType: IMessageTypingBubbleView.self,
    backgroundColor: .clear,
    highlightColor: .clear,
    selectedColor: .clear,
    primaryContentColor: .systemGray5,
    secondaryContentColor: .systemGray2,
    animationEnabled: true,
    pulsing: true,
    bounces: true,
    bounceDelay: 0.33,
    bounceOffset: 0.25,
    fades: true
  )
)
```

You can configure the `MessageListComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `controllerType` | `ComponentViewController.Type` | No | Default class type that's used when creating new `UIViewController` instances. |
| `backgroundColor` | `UIColor?` | Yes | View Controller’s background color. |
| `collectionViewTheme` | `CollectionViewComponentTheme` | Yes | Theming for `UICollectionView` found on the `UIViewController` component. |
| `incomingItemTheme` | `MessageListCellComponentTheme` | Yes | Theming for messages that are sent from users other than the current user. |
| `authorItemTheme` | `MessageListCellComponentTheme?` | Yes | Theming for messages that are sent from the current user. |
| `typingIndicatorCellTheme` | `TypingIndicatorCellTheme` | Yes | Theming for `UICollectionViewCell` that's displayed when another member is typing. |

You can configure the `MessageListCellComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `textMessageContentCellType` | `CollectionViewCellComponent.Type` | No | Default class for the `UICollectionViewCell` specific to text based messages. |
| `richMessageContentCellTypes` | `[MessageContentType: CollectionViewCellComponent.Type]` | No | `Dictionary` that maps `UICollectionViewCell` class types to known rich message content types. |
| `backgroundColor` | `UIColor?` | Yes | View's background color. |
| `highlightColor` | `UIColor?` | Yes | View's background color during highlighted state. |
| `selectedColor` | `UIColor?` | Yes | View's background color during selected state. |
| `alignment` | `UICollectionViewCell.Alignment` | Yes | Vertical list edge the message is anchored to. |
| `maxWidthPercentage` | `CGFloat` | Yes | Maximum width a `Cell` spans inside the message list frame. |
| `bubbleContainerTheme` | `BubbleComponentTheme` | Yes | Theming for the bubble view container you can wrap around message content. |
| `contentTextTheme` | `TextViewComponentTheme` | Yes | Theming for `UITextView` that displays message text content. |
| `contentLinkTheme` | `LinkViewComponentTheme` | Yes | Theming for `LPLinkView` that displays message URL content. |
| `itemTheme` | `BasicComponentTheme` | Yes | Theming for the accessory views around the message content. |
| `dateFormatter` | `DateFormatter` | Yes | `DataFormatter` used when displaying message dates. |

You can configure the `TypingIndicatorCellTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `cellType` | `CollectionViewCellComponent.Type` | No | Default class for `UICollectionViewCell` when creating typing indicator cells. |
| `contentViewType` | `UIView` | No | Default class for `contentView` inside the `UICollectionViewCell` typing indicator. |
| `backgroundColor` | `UIColor?` | Yes | View's background color. |
| `highlightColor` | `UIColor?` | Yes | View's background color during highlighted state. |
| `selectedColor` | `UIColor?` | Yes | View's background color during selected state. |
| `alignment` | `UICollectionViewCell.Alignment` | Yes | The vertical list edge `contentViewType` is anchored to. |
| `primaryContentColor` | `UIColor?` | Yes | Primary color by the `contentViewType` view. |
| `secondaryContentColor` | `UIColor?` | Yes | Secondary color used by the `contentViewType` view. |
| `animationEnabled` | `Bool` | No | Whether the typing indicator is animated. |
| `pulsing` | `Bool` | No | Whether the typing indicator animation pulses. |
| `bounces` | `Bool` | No | Whether the typing indicator animation bounces. |
| `bounceDelay` | `TimeInterval` | No | Delay between each distinct sub-view's bounce animation. |
| `bounceOffset` | `CGFloat` | No | Distance each distinct sub-view bounces during its animation. |
| `fades` | `Bool` | No | Whether the typing indicator animation fades as it animates. |

### MessageInput

The default implementation is available through `MessageInputComponentTheme.pubnubGroupChat` which is composed of the following values:

```swift
MessageInputComponentTheme(
  viewType: MessageInputBarComponent.self,
  backgroundColor: .secondarySystemBackground,
  placeholderText: "Type Message",
  placeholderTextColor: .systemGray2,
  placeholderTextFont: AppearanceTemplate.Font.body,
  textInputTheme: InputTextViewComponentTheme(
    customType: UITextView.self,
    backgroundColor: .tertiarySystemBackground,
    textColor: .systemGray2,
    textFont: AppearanceTemplate.Font.body,
    usesStandardTextScaling: true,
    dataDetectorTypes: .all,
    linkTextAttributes: [:],
    isEditable: true,
    isExclusiveTouch: false,
    scrollView: .enabled,
    textContainerInset: .zero,
    typingAttributes: [:],
    autocapitalizationType: .sentences,
    autocorrectionType: .default,
    spellCheckingType: .default,
    smartQuotesType: .default,
    smartDashesType: .default,
    smartInsertDeleteType: .default,
    keyboardType: .default,
    keyboardAppearance: .default,
    textContentType: nil
  ),
  sendButton: ButtonComponentTheme(
    backgroundColor: .clear,
    tintColor: .systemBlue,
    title: .empty,
    titleHighlighted: .empty,
    titleFont: AppearanceTemplate.Font.caption1,
    image: ButtonImageStateTheme(
      image: UIImage(systemName: "paperplane.fill")?.rotate(degree: 45)?.withTintColor(.systemBlue),
      backgroundImage: nil
    ),
    imageHighlighted: .empty
  ),
  typingIndicatorService: .shared,
  publishTypingIndicator: true,
  displayTypingIndicator: true
)
```

You can configure the `MessageInputComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `viewType` | `MessageInputComponent` | No | Default class type that's used when creating new view instances. |
| `backgroundColor` | `UIColor?` | Yes | View’s background color. |
| `placeholderText` | `String?` | Yes | Text that appears whens the user hasn't entered the text. |
| `placeholderTextColor` | `UIColor?` | Yes | Placeholder text's color. |
| `placeholderTextFont` | `UIFont?` | Yes | Placeholder text's font. |
| `textInputTheme` | `InputTextViewComponentTheme` | Yes | Theming for `UITextView` used as the input view. |
| `sendButtonTheme` | `ButtonComponentTheme` | Yes | Theming for `UIButton` responsible for sending message input. |
| `typingIndicatorService` | `TypingIndicatorService` | No | Service that coordinates typing indicator events across all channels. |
| `publishTypingIndicator` | `Bool` | Yes | Whether typing indicator signals are sent to other chat users. |
| `displayTypingIndicator` | `Bool` | Yes | Whether typing indicator signals are displayed from other chat users. |

You can configure the `ButtonComponentTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `backgroundColor` | `UIColor?` | Yes | View’s background color. |
| `tintColor` | `UIColor?` | Yes | Tint color to apply to the button title and image. |
| `title` | `ButtonTitleStateTheme` | Yes | Title during normal button state. |
| `titleHighlighted` | `ButtonTitleStateTheme` | Yes | Title during highlighted button state. |
| `titleFont` | `UIFont?` | Yes | Font of the button text. |
| `image` | `ButtonImageStateTheme` | Yes | Image during normal button state. |
| `imageHighlighted` | `ButtonImageStateTheme` | Yes | Image during highlighted button state. |

You can configure the `ButtonTitleStateTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `title` | `String?` | Yes | Title that the button displays. |
| `attributedTitle` | `NSAttributedString?` | Yes | Styled text that the button displays. |
| `titleColor` | `UIColor?` | Yes | Color of the text. |
| `titleShadowColor` | `UIColor?` | Yes | Shadow color of the text. |

You can configure the `ButtonImageStateTheme` theme using the following parameters.

| Name | Type | Auto update on change | Description |
| --- | --- | --- | --- |
| `image` | `UIImage?` | Yes | Image used for a button state. |
| `backgroundImage` | `UIImage?` | Yes | Background image used for a button state. |

## Customize component themes

UI component and element themes provide theming skeletons that set limitations as to what you can theme in PubNub Chat Components for iOS. For example, if you look at [BasicComponentTheme](https://github.com/pubnub/chat-components-ios/blob/master/Sources/PubNubChatComponents/Theming/ThemeProvider.swift), you can see it only supports theming for one image and four different labels. This means that if you define an additional image for your cell item, you will only be able to theme one of them by default.

```swift
public class BasicComponentTheme: ObservableObject {
  // Appearance
  @Published public var imageView: ImageComponentTheme
  @Published public var primaryLabel: LabelComponentTheme
  @Published public var secondaryLabel: LabelComponentTheme
  @Published public var tertiaryLabel: LabelComponentTheme
  @Published public var quaternaryLabel: LabelComponentTheme
```

Look at the three use cases to see how you can customize some basic appearance values provided by our default themes.

### Change message list bubble color

Customize the message list bubble color to be different depending on whether the message in a chat is sent by you (`authorItemTheme`) or someone else (`incomingItemTheme`).

```swift
// Create a configured Chat Provider
let config =PubNubConfiguration(
  publishKey: PUBNUB_PUBLISH_KEY,
  subscribeKey: PUBNUB_SUBSCRIBE_KEY,
  userId: "myFirstUser"
)

var provider = PubNubChatProvider(
  pubnubProvider: PubNub(configuration: pubnubConfiguration)
)

// Set the message bubble color for incoming messages
provider.themeProvider.template.messageListComponent
  .incomingItemTheme.bubbleContainerTheme.backgroundColor = .systemGray

// Set the message bubble color for outgoing messages
provider.themeProvider.template.messageListComponent
  .authorItemTheme.bubbleContainerTheme.backgroundColor = .systemBlue
```

As you can see, to change these colors you must call the Chat Provider through the `themeProvider` wrapper and reference the default template for the `messageListComponent`. Since `backgroundColor` for the incoming (`incomingItemTheme`) and outgoing (`authorItemTheme`) message bubble is defined in the `bubbleContainerTheme`, you can define them separately with different system colors.

### Change the message sender's name

Change the font for the message sender name that appears above the message:

```swift
// Create a configured Chat Provider
let config =PubNubConfiguration(
  publishKey: PUBNUB_PUBLISH_KEY,
  subscribeKey: PUBNUB_SUBSCRIBE_KEY,
  userId: "myFirstUser"
)

var provider = PubNubChatProvider(
  pubnubProvider: PubNub(configuration: pubnubConfiguration)
)

// Change the font for the name of the message sender
provider.themeProvider.template.messageListComponent
  .incomingItemTheme.itemTheme.primaryLabel.textFont = UIFont.preferredFont(forTextStyle: .headline)
```

As you can see, to change the font, you must call the Chat Provider through the `themeProvider` wrapper and reference the default template for `messageListComponent`. Define the `headline` font by overriding the default `textFont` parameter value. This parameter is nested down the theme hierarchy and its structure looks as follows:

* `MessageListComponentTheme` contains `incomingItemTheme` of the `MessageListCellComponentTheme` type:

```swift
public class MessageListComponentTheme: ViewControllerComponentTheme {
  ...
  @Published public var incomingItemTheme: MessageListCellComponentTheme
  ...
}
```

* `MessageListCellComponentTheme` contains `itemTheme` of the `BasicComponentTheme` type:

```swift
public class MessageListCellComponentTheme: CollectionViewCellTheme {
  ...
  @Published public var itemTheme: BasicComponentTheme
  ...
}
```

* `BasicComponentTheme` contains `primaryLabel` of the `LabelComponentTheme` type:

```swift
public class BasicComponentTheme: ObservableObject {
  ...
  @Published public var primaryLabel: LabelComponentTheme
  ...
  }
```

* Finally, `LabelComponentTheme` contains the `textFont` parameter that's of the `UIFont?` type. This is the parameter you must override.

```swift
open class LabelComponentTheme: ObservableObject {
  ...
  @Published public var textFont: UIFont?
  ...
```

### Change placeholder text for message input

Replace the default `"Type Message"` placeholder text of the message input associated with the `MessageList` component.

```swift
// Create a configured Chat Provider
let config = PubNubConfiguration(
  publishKey: PUBNUB_PUBLISH_KEY,
  subscribeKey: PUBNUB_SUBSCRIBE_KEY,
  userId: "myFirstUser"
)

var provider = PubNubChatProvider(
  pubnubProvider: PubNub(configuration: pubnubConfiguration)
)

// Change the string to be the desired placeholder text
provider.themeProvider.template.messageListComponent
  .messageInputComponent.placeholderText = "Message..."
```

To change this text, call the Chat Provider through the `themeProvider` wrapper and reference the default template for the `messageListComponent`. Override the default value of `"Type Message"` that the `placeholderText` defines in the `messageInputComponent` that's a subclass of `messageListComponent`.