> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Message Header

## Overview

`MessageHeader` is a [Component](/ui-kit/ios/components-overview#components) that showcases the [User](/sdk/ios/users-overview) or [Group](/sdk/ios/groups-overview) details in the toolbar. Furthermore, it also presents a typing indicator and a back navigation button for ease of use.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/cL0h7qQ6VW0ex7sa/images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png?fit=max&auto=format&n=cL0h7qQ6VW0ex7sa&q=85&s=d4264d7c0cbf2929a76f2421f9b96eb4" width="1280" height="240" data-path="images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png" />
</Frame>

The `MessageHeader` is comprised of the following components:

| Components                                  | Description                                                                                                                                    |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| [ListItem Component](/ui-kit/ios/list-item) | This component’s view consists of avatar, status indicator , title, and subtitle. The fields are then mapped with the SDK’s user, group class. |
| Back Button                                 | BackButton that allows users to navigate back from the current activity or screen to the previous one                                          |

## Usage

### Integration

You can add `MessageHeader` component directly by setting the user.

```ruby Swift theme={null}
// syntax for set(user: User)
messageHeader.set(user: user)	 // The object which is going to be rendered in the data item
```

### Actions

[Actions](/ui-kit/ios/components-overview#actions) dictate how a component functions. They are divided into two types: Predefined and User-defined. You can override either type, allowing you to tailor the behavior of the component to fit your specific needs.

The `MessageHeader` component does not have any exposed actions.

##### 1. set(onBack:)

This `set(onBack:)` method becomes valuable when a user needs to override the action triggered upon pressing the back button in CometChatMessageHeader.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(onBack: {
        // Override on back
    })
    ```
  </Tab>
</Tabs>

***

##### 2. set(onError:)

This method proves helpful when a user needs to customize the action taken upon encountering an error in CometChatMessageHeader.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(onError: { error in
        // Override on error
    })
    ```
  </Tab>
</Tabs>

***

### Filters

**Filters** allow you to customize the data displayed in a list within a `Component`. You can filter the list based on your specific criteria, allowing for a more customized. Filters can be applied using `RequestBuilders` of Chat SDK.

The `MessageHeader` component does not have any exposed filters.

### Events

[Events](/ui-kit/ios/components-overview#events) are emitted by a `Component`. By using event you can extend existing functionality. Being global events, they can be applied in Multiple Locations and are capable of being Added or Removed.

The `MessageHeader` component does not produce any events.

## Customization

To fit your app's design requirements, you can customize the appearance of the conversation component. We provide exposed methods that allow you to modify the experience and behavior according to your specific needs.

### Style

Using Style you can customize the look and feel of the component in your app, These parameters typically control elements such as the color, size, shape, and fonts used within the component.

##### 1. MessageHeader Style

To customize the appearance, you can assign a `MessageHeaderStyle` object to the `MessageHeader` component.

**Global level styling**

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.backgroundColor = UIColor(hex: "#FBAA75")
    customAvatarStyle.textFont = UIFont(name: "Times-New-Roman", size: 18)
            
    CometChatMessageHeader.style.titleTextColor = UIColor(hex: "#F76808")
    CometChatMessageHeader.style.titleTextFont = UIFont(name: "Times-New-Roman", size: 16)
    CometChatMessageHeader.style.subtitleTextFont = UIFont(name: "Times-New-Roman", size: 12)
    CometChatMessageHeader.style.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

**Instance level styling**

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.backgroundColor = UIColor(hex: "#FBAA75")
    customAvatarStyle.textFont = UIFont(name: "Times-New-Roman", size: 18)
            
    let messageHeaderStyle = MessageHeaderStyle()
    messageHeaderStyle.titleTextColor = UIColor(hex: "#F76808")
    messageHeaderStyle.titleTextFont = UIFont(name: "Times-New-Roman", size: 16)
    messageHeaderStyle.subtitleTextFont = UIFont(name: "Times-New-Roman", size: 12)
            
    let messageHeader = CometChatMessageHeader()
    messageHeader.style = messageHeaderStyle
    messageHeader.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/P03UjDxM6EbWn5rE/images/54a6e640-message-header-style-d4203b4eece8507a4e5750d88e7fa913.png?fit=max&auto=format&n=P03UjDxM6EbWn5rE&q=85&s=83ae2a3fd483ac6454a9744f7efaa26c" width="1280" height="240" data-path="images/54a6e640-message-header-style-d4203b4eece8507a4e5750d88e7fa913.png" />
</Frame>

The properties exposed by `MessageHeaderStyle` are as follows:

| **Property**                            | **Description**                                                                 | **Code**                                                                                  |
| --------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Title Text Color**                    | Used to set the text color of the header title.                                 | `CometChatMessageHeader.style.titleTextColor = UIColor.black`                             |
| **Title Text Font**                     | Used to set the font style of the header title.                                 | `CometChatMessageHeader.style.titleTextFont = UIFont.boldSystemFont(ofSize: 18)`          |
| **Subtitle Text Color**                 | Used to set the text color of the subtitle in the header.                       | `CometChatMessageHeader.style.subtitleTextColor = UIColor.gray`                           |
| **Subtitle Text Font**                  | Used to set the font style of the subtitle in the header.                       | `CometChatMessageHeader.style.subtitleTextFont = UIFont.systemFont(ofSize: 14)`           |
| **Back Button Image Tint Color**        | Used to set the tint color of the back button image in the header.              | `CometChatMessageHeader.style.backButtonImageTintColor = UIColor.blue`                    |
| **Private Group Badge Tint Color**      | Used to set the tint color of the private group badge in the header.            | `CometChatMessageHeader.style.privateGroupBadgeImageTintColor = UIColor.green`            |
| **Password-Protected Badge Tint Color** | Used to set the tint color of the password-protected group badge in the header. | `CometChatMessageHeader.style.passwordProtectedGroupBadgeImageTintColor = UIColor.orange` |
| **Private Group Background Color**      | Used to set the background color of the private group badge.                    | `CometChatMessageHeader.style.privateGroupImageBackgroundColor = UIColor.lightGray`       |
| **Password-Protected Background Color** | Used to set the background color of the password-protected group badge.         | `CometChatMessageHeader.style.passwordGroupImageBackgroundColor = UIColor.red`            |
| **Group Image Background Color**        | Used to set the background color for group icons in the header.                 | `CometChatMessageHeader.style.groupImageBackgroundColor = UIColor.clear`                  |
| **Avatar Style**                        | Used to customize the appearance of the avatar in the header.                   | `CometChatMessageHeader.style.avatarStyle = customAvatarStyle`                            |
| **Background Color**                    | Used to set the background color of the header.                                 | `CometChatMessageHeader.style.backgroundColor = UIColor.white`                            |
| **Corner Radius**                       | Used to set the corner radius of the header.                                    | `CometChatMessageHeader.style.cornerRadius = CometChatCornerStyle(cornerRadius: 8)`       |
| **Border Width**                        | Used to set the border width of the header.                                     | `CometChatMessageHeader.style.borderWidth = 2`                                            |
| **Border Color**                        | Used to set the border color of the header.                                     | `CometChatMessageHeader.style.borderColor = UIColor.gray`                                 |
| **Back Button Icon**                    | Used to set a custom icon for the back button.                                  | `CometChatMessageHeader.style.backButtonIcon = UIImage(named: "customBackIcon")`          |
| **Private Group Icon**                  | Used to set a custom icon for private groups.                                   | `CometChatMessageHeader.style.privateGroupIcon = UIImage(named: "privateIcon")`           |
| **Protected Group Icon**                | Used to set a custom icon for password-protected groups.                        | `CometChatMessageHeader.style.protectedGroupIcon = UIImage(named: "protectedIcon")`       |
| **Background Image**                    | Used to set a background image for the header.                                  | `CometChatMessageHeader.style.backgroundImage = UIImage(named: "headerBackground")`       |
| **New Chat Icon**                       | Sets a custom icon for the new chat button for AI agent.                        | `CometChatAIAssistantChatHistory.newChatIcon = UIImage(named: "iconName")`                |
| **Chat History Icon**                   | Sets a custom icon for the chat history button for AI agent.                    | `CometChatAIAssistantChatHistory.chatHistoryIcon = UIImage(named: "iconName")`            |

##### 2. Avatar Style

If you want to apply customized styles to the `Avatar` component within the `MessageHeader` Component, you can use the following code snippet. For more information you can refer [Avatar Styles](/ui-kit/ios/component-styling#avatar#methods).

**Global level styling**

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
            
    CometChatMessageHeader.style.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

**Instance level styling**

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
                    
    let messageHeader = CometChatMessageHeader()
    messageHeader.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/45sEoks_X3i4sdzA/images/a2f4d179-header-avatar-style-b31d058753670e28959f222088f64109.png?fit=max&auto=format&n=45sEoks_X3i4sdzA&q=85&s=29c4b428b4815678aa959a99805c40d8" width="1280" height="240" data-path="images/a2f4d179-header-avatar-style-b31d058753670e28959f222088f64109.png" />
</Frame>

***

### Functionality

These are a set of small functional customizations that allow you to fine-tune the overall experience of the component. With these, you can change text, set custom icons, and toggle the visibility of UI elements.

Below is a list of customizations along with corresponding code snippets

| Method                 | Description                                                            | Code                                                                       |
| ---------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| set(user:User)         | Sets message header for CometChat user.                                | `.set(user:User)`                                                          |
| set(group:Group)       | Sets message header for CometChat group.                               | `.set(group:Group)`                                                        |
| hideBackButton         | Hides the back button of message header.                               | `hideBackButton = true`                                                    |
| hideUserStatus         | Hides or shows the user status of user(online/offline/last active at). | `hideUserStatus = true`                                                    |
| hideVideoCallButton    | Hides the video call button.                                           | `hideVideoCallButton = true`                                               |
| hideVoiceCallButton    | Hides the voice call button.                                           | `hideVoiceCallButton = true`                                               |
| hideChatHistoryButton  | Hides the chat history button in the component.                        | `CometChatAIAssistantChatHistory.hideChatHistoryButton = true`             |
| hideNewChatButton      | Hides the new chat button in the component for AI agent.               | `CometChatAIAssistantChatHistory.hideNewChatButton = true`                 |
| onNewChatButtonClicked | Used to handle actions when the “New Chat” button is clicked.          | `CometChatAIAssistantChatHistory.set(onNewChatButtonClicked: { user in })` |
| onMessageClicked       | Used to handle actions when a message is clicked.                      | `CometChatAIAssistantChatHistory.set(onMessageClicked: { message in })`    |

***

### Advanced

For advanced-level customization, you can set custom views to the component. This lets you tailor each aspect of the component to fit your exact needs and application aesthetics. You can create and define your views, layouts, and UI elements and then incorporate those into the component.

#### Date Time Formatter

The **CometChatMessageHeader** component supports full customization of how date and time are displayed using the [CometChatDateTimeFormatter](/ui-kit/ios/localize#datetimeformatter).

This enables developers to localize, format, or personalize the date and time strings shown next to the message header such as “Today”, “Yesterday”, “12:45 PM”, etc.

1. Component-Level (Global)

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatMessageHeader.dateTimeFormatter.time = { timestamp in
        return "Last seen at " + DateFormatter.localizedString(from: Date(timeIntervalSince1970: TimeInterval(timestamp)), dateStyle: .none, timeStyle: .short)
    }

    CometChatMessageHeader.dateTimeFormatter.today = { timestamp in
        return "Last seen: Today • \(formattedTime(from: timestamp))"
    }

    CometChatMessageHeader.dateTimeFormatter.otherDay = { timestamp in // This will display older dates as "24 Apr 2025" instead of the default relative format.
        let formatter = DateFormatter()
        formatter.dateFormat = "dd MMM yyyy"
        return formatter.string(from: Date(timeIntervalSince1970: TimeInterval(timestamp)))
    }
    ```
  </Tab>
</Tabs>

2. Instance-Level (Local)

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let messageHeader = CometChatMessageHeader()
    messageHeader.dateTimeFormatter.yesterday = { timestamp in
        return "Yesterday at " + formattedTime(from: timestamp)
    }
    ```
  </Tab>
</Tabs>

##### Available closures

| Property  | Description                                                         | Code                                                           |
| --------- | ------------------------------------------------------------------- | -------------------------------------------------------------- |
| time      | Called to format a timestamp as a standard time (e.g., "12:30 PM"). | `CometChatMessageHeader.dateTimeFormatter.time = { ... }`      |
| today     | Called when rendering messages sent today.                          | `CometChatMessageHeader.dateTimeFormatter.today = { ... }`     |
| yesterday | Called for yesterday's messages.                                    | `CometChatMessageHeader.dateTimeFormatter.yesterday = { ... }` |
| lastweek  | Called for messages within the last week.                           | `CometChatMessageHeader.dateTimeFormatter.lastweek = { ... }`  |
| otherDay  | Called for dates older than last week.                              | `CometChatMessageHeader.dateTimeFormatter.otherDay = { ... }`  |
| minute    | Called when referring to "a minute ago".                            | `CometChatMessageHeader.dateTimeFormatter.minute = { ... }`    |
| minutes   | Called for "x minutes ago".                                         | `CometChatMessageHeader.dateTimeFormatter.minutes = { ... }`   |
| hour      | Called for "an hour ago".                                           | `CometChatMessageHeader.dateTimeFormatter.hour = { ... }`      |
| hours     | Called for "x hours ago".                                           | `CometChatMessageHeader.dateTimeFormatter.hours = { ... }`     |

Each closure receives a timestamp (Int, representing UNIX time) and must return a String representing the formatted time.

***

#### SetListItemView

With this function, you can assign a custom ListItem to the message header Component.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let cometChatMessageHeader = CometChatMessageHeader()
    cometChatMessageHeader.set(listItemView: { user, group in
        let view = CustomListItemView()
        return view
    })
    ```
  </Tab>
</Tabs>

Demonstration

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/ASAuj03ZuUm-dFU-/images/0a9c996b-headerLisItem-84b7b1afda8328d5386b24f865247023.png?fit=max&auto=format&n=ASAuj03ZuUm-dFU-&q=85&s=73a861d0fd58cd9a17d2c512b12a5d4f" width="1280" height="240" data-path="images/0a9c996b-headerLisItem-84b7b1afda8328d5386b24f865247023.png" />
</Frame>

You can create a `CustomListItemView` as a custom `UIView`. Which we will inflate in `setListItemView()`

```swift swift theme={null}
import UIKit

class CustomListItemView: UIView {

    private let backButton: UIButton = {
        let button = UIButton(type: .system)
        let image = UIImage(systemName: "chevron.left")?.withRenderingMode(.alwaysTemplate)
        button.setImage(image, for: .normal)
        button.tintColor = .black
        return button
    }()

    private let profileImageView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.systemPurple
        view.layer.cornerRadius = 18
        view.clipsToBounds = true

        let label = UILabel()
        label.text = "GA"
        label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        label.textColor = .white
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(label)

        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])

        return view
    }()

    private let nameLabel: UILabel = {
        let label = UILabel()
        label.text = "George Alan"
        label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        label.textColor = .black
        return label
    }()

    private let statusLabel: UILabel = {
        let label = UILabel()
        label.text = "Online"
        label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
        label.textColor = .gray
        return label
    }()

    private let videoCallButton: UIButton = {
        let button = UIButton(type: .system)
        let image = UIImage(systemName: "video.fill")?.withRenderingMode(.alwaysTemplate)
        button.setImage(image, for: .normal)
        button.tintColor = .black
        return button
    }()

    private let callButton: UIButton = {
        let button = UIButton(type: .system)
        let image = UIImage(systemName: "phone.fill")?.withRenderingMode(.alwaysTemplate)
        button.setImage(image, for: .normal)
        button.tintColor = .black
        return button
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupView() {
        backgroundColor = .white

        let userInfoStack = UIStackView(arrangedSubviews: [nameLabel, statusLabel])
        userInfoStack.axis = .vertical
        userInfoStack.spacing = 2
        userInfoStack.alignment = .leading

        let rightButtonsStack = UIStackView(arrangedSubviews: [videoCallButton, callButton])
        rightButtonsStack.axis = .horizontal
        rightButtonsStack.spacing = 16

        addSubview(backButton)
        addSubview(profileImageView)
        addSubview(userInfoStack)
        addSubview(rightButtonsStack)

        backButton.translatesAutoresizingMaskIntoConstraints = false
        profileImageView.translatesAutoresizingMaskIntoConstraints = false
        userInfoStack.translatesAutoresizingMaskIntoConstraints = false
        rightButtonsStack.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            backButton.centerYAnchor.constraint(equalTo: centerYAnchor),
            backButton.widthAnchor.constraint(equalToConstant: 30),
            backButton.heightAnchor.constraint(equalToConstant: 30),

            profileImageView.leadingAnchor.constraint(equalTo: backButton.trailingAnchor, constant: 10),
            profileImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
            profileImageView.widthAnchor.constraint(equalToConstant: 36),
            profileImageView.heightAnchor.constraint(equalToConstant: 36),

            userInfoStack.leadingAnchor.constraint(equalTo: profileImageView.trailingAnchor, constant: 10),
            userInfoStack.centerYAnchor.constraint(equalTo: centerYAnchor),

            rightButtonsStack.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            rightButtonsStack.centerYAnchor.constraint(equalTo: centerYAnchor)
        ])
    }
}
```

***

#### SetLeadingView

You can modify the leading view of a group cell using .set(leadingView:).

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(leadingView: { user, group in  
        let view = CustomLeadingView()
        return view  
    })  
    ```
  </Tab>
</Tabs>

Demonstration

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/yDKVamMkf61gj3YR/images/e6fad16f-headerLeadng-6f55e63eb8a291dfe2a06771801f2337.png?fit=max&auto=format&n=yDKVamMkf61gj3YR&q=85&s=14d0d45181baf33bdbd99d27551430ef" width="1280" height="240" data-path="images/e6fad16f-headerLeadng-6f55e63eb8a291dfe2a06771801f2337.png" />
</Frame>

You can create a `CustomLeadingView` as a custom `UIView`. Which we will inflate in `setLeadingView()`

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    import UIKit

    class CustomLeadingView: UIView {

        private let profileImageView: UIImageView = {
            let imageView = UIImageView()
            imageView.contentMode = .scaleAspectFill
            imageView.layer.cornerRadius = 20
            imageView.clipsToBounds = true
            imageView.backgroundColor = .lightGray // Placeholder color
            imageView.image = UIImage(systemName: "person.fill")
            return imageView
        }()

        private let joinButton: UIButton = {
            let button = UIButton()
            button.setTitle("Join", for: .normal)
            button.setTitleColor(.white, for: .normal)
            button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold)
            button.backgroundColor = .orange
            button.layer.cornerRadius = 6
            button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
            button.setImage(UIImage(systemName: "star.circle"), for: .normal)
            button.setTitle("Admin", for: .normal)
            return button
        }()

        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }

        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private func setupView() {
            addSubview(profileImageView)
            addSubview(joinButton)

            profileImageView.translatesAutoresizingMaskIntoConstraints = false
            joinButton.translatesAutoresizingMaskIntoConstraints = false

            NSLayoutConstraint.activate([
                profileImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
                profileImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
                profileImageView.topAnchor.constraint(equalTo: topAnchor),
                profileImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
                profileImageView.heightAnchor.constraint(equalToConstant: 40),
                profileImageView.widthAnchor.constraint(equalToConstant: 40),

                joinButton.trailingAnchor.constraint(equalTo: profileImageView.trailingAnchor),
                joinButton.leadingAnchor.constraint(equalTo: profileImageView.leadingAnchor),
                joinButton.bottomAnchor.constraint(equalTo: profileImageView.bottomAnchor),
                joinButton.heightAnchor.constraint(equalToConstant: 12)
            ])
        }
    }
    ```
  </Tab>
</Tabs>

***

#### SetTitleView

You can customize the title view of a group cell using .set(titleView:).

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(titleView: { user, group in  
        let view = CustomTitleView()
        return view
    })  
    ```
  </Tab>
</Tabs>

Demonstration

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/why4qwLRU92tDIid/images/77d20b8c-headerTitle-20200a0eddfa0c9f2337abb9511a9671.png?fit=max&auto=format&n=why4qwLRU92tDIid&q=85&s=ed3594d0c4d5ceb7e7981f92e0c89ebb" width="1280" height="240" data-path="images/77d20b8c-headerTitle-20200a0eddfa0c9f2337abb9511a9671.png" />
</Frame>

You can create a `CustomTitleView` as a custom `UIView`. Which we will inflate in `setTitleView()`

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
     class CustomTitleView: UIView {

        private let titleLabel: UILabel = {
            let label = UILabel()
            label.text = "Artistic Design"
            label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
            label.textColor = .black
            return label
        }()

        private let publicBadge: UIView = {
            let view = UIView()
            view.backgroundColor = .blue
            view.layer.cornerRadius = 10

            let icon = UIImageView(image: UIImage(systemName: "person.3.fill"))
            icon.tintColor = .white
            icon.contentMode = .scaleAspectFit

            let label = UILabel()
            label.text = "Public"
            label.font = UIFont.systemFont(ofSize: 12, weight: .bold)
            label.textColor = .white

            let stackView = UIStackView(arrangedSubviews: [icon, label])
            stackView.spacing = 4
            stackView.alignment = .center
            stackView.translatesAutoresizingMaskIntoConstraints = false

            view.addSubview(stackView)

            NSLayoutConstraint.activate([
                stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                view.widthAnchor.constraint(equalToConstant: 60),
                view.heightAnchor.constraint(equalToConstant: 20)
            ])
            
            return view
        }()

        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }

        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private func setupView() {
            addSubview(titleLabel)
            addSubview(publicBadge)

            titleLabel.translatesAutoresizingMaskIntoConstraints = false
            publicBadge.translatesAutoresizingMaskIntoConstraints = false

            NSLayoutConstraint.activate([
                titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
                titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),

                publicBadge.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 6),
                publicBadge.centerYAnchor.constraint(equalTo: centerYAnchor)
            ])
        }
    }
    ```
  </Tab>
</Tabs>

***

#### SetTrailView

You can modify the trailing view of a message header using .set(trailView:).

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(trailView: { user, group in  
        let view = CustomTrailView() 
        return view  
    })  
    ```
  </Tab>
</Tabs>

Demonstration

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/494NzpIb6o8839I0/images/7ae625d7-headerTrail-b0c07329c262e97434036abff2c0132d.png?fit=max&auto=format&n=494NzpIb6o8839I0&q=85&s=bda09e1c129efc6655dd3a2307924843" width="1280" height="240" data-path="images/7ae625d7-headerTrail-b0c07329c262e97434036abff2c0132d.png" />
</Frame>

You can create a `CustomTrailView` as a custom `UIView`. Which we will inflate in `setTrailView()`

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    import UIKit

    class CustomTrailView: UIView {

        private let videoCallButton: UIButton = {
            let button = UIButton(type: .system)
            let image = UIImage(systemName: "video.fill")?.withRenderingMode(.alwaysTemplate)
            button.setImage(image, for: .normal)
            button.tintColor = .black
            return button
        }()

        private let callButton: UIButton = {
            let button = UIButton(type: .system)
            let image = UIImage(systemName: "phone.fill")?.withRenderingMode(.alwaysTemplate)
            button.setImage(image, for: .normal)
            button.tintColor = .black
            return button
        }()
        
        private let bookMarkButton: UIButton = {
            let button = UIButton(type: .system)
            let image = UIImage(systemName: "phone.fill")?.withRenderingMode(.alwaysTemplate)
            button.setImage(image, for: .normal)
            button.tintColor = .black
            return button
        }()

        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }

        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private func setupView() {

            let buttonsStack = UIStackView(arrangedSubviews: [videoCallButton, callButton])
            buttonsStack.axis = .horizontal
            buttonsStack.spacing = 16
            buttonsStack.distribution = .fillEqually

            buttonsStack.addArrangedSubview(videoCallButton)
            buttonsStack.addArrangedSubview(callButton)
            buttonsStack.addArrangedSubview(bookMarkButton)
            
            buttonsStack.translatesAutoresizingMaskIntoConstraints = false

            NSLayoutConstraint.activate([
                buttonsStack.leadingAnchor.constraint(equalTo: leadingAnchor),
                buttonsStack.trailingAnchor.constraint(equalTo: trailingAnchor),
                buttonsStack.topAnchor.constraint(equalTo: topAnchor),
                buttonsStack.bottomAnchor.constraint(equalTo: bottomAnchor)
            ])
        }
    }
     
    ```
  </Tab>
</Tabs>

***

#### SetSubTitleView

You can customize the subtitle view for each group item to meet your requirements

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    cometChatMessageHeader.set(subtitleView: { user, group in
       let view = CustomSubtitleView()
       return view
    })
    ```
  </Tab>
</Tabs>

**Example**

Demonstration

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/_FWwfJpY0a1-Jsg7/images/da6d6843-groups_subtitle_view-6e73eb325145dd0670dc66bbf32e41d0.png?fit=max&auto=format&n=_FWwfJpY0a1-Jsg7&q=85&s=f72baee585419d2f49bc2fe8a4e1ca40" width="1280" height="800" data-path="images/da6d6843-groups_subtitle_view-6e73eb325145dd0670dc66bbf32e41d0.png" />
</Frame>

You can seamlessly integrate this `CustomSubtitleView` UIView file into the `.set(subtitleView:)` method within CometChatMessageHeader.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    import UIKit

    class CustomSubtitleView: UILabel {
        
        init(membersCount: Int) {
            super.init(frame: .zero)
            self.text = "\(membersCount) members • \("group_description")"
            self.textColor = UIColor.gray
            self.font = UIFont.systemFont(ofSize: 14)
            self.numberOfLines = 1
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    ```
  </Tab>
</Tabs>

***

<Note>
  To ensure that the `MessageHeader` is properly configured, passing the controller is mandatory.

  * Swift

  ```swift theme={null}
  let headerView = CometChatMessageHeader()
  headerView.set(controller: UIViewController) // Passing the controller is required
  ```
</Note>
