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

# Message Header

> Configure CometChat iOS UI Kit Message Header with user or group details, avatar, status, typing indicators, navigation, and call buttons.

The `CometChatMessageHeader` component displays user or group details in the toolbar including avatar, name, status, and typing indicators. It also provides navigation controls and call buttons.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/wpH0oTjPapnxuXny/images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png?fit=max&auto=format&n=wpH0oTjPapnxuXny&q=85&s=0bfbcecb645bf542dbf0bb7633df8bb7" alt="CometChatMessageHeader showing user avatar, name, online status, and call buttons in the navigation bar" width="1280" height="240" data-path="images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png" />
</Frame>

<Accordion title="AI Integration Quick Reference">
  ```json theme={null}
  {
    "component": "CometChatMessageHeader",
    "package": "CometChatUIKitSwift",
    "import": "import CometChatUIKitSwift\nimport CometChatSDK",
    "description": "Displays user or group details in the toolbar with avatar, name, status, typing indicators, and navigation controls.",
    "inherits": "UIView",
    "primaryOutput": {
      "callback": "onBack",
      "type": "() -> Void"
    },
    "props": {
      "data": {
        "user": {
          "type": "User?",
          "default": "nil",
          "note": "User to display in header"
        },
        "group": {
          "type": "Group?",
          "default": "nil",
          "note": "Group to display in header"
        }
      },
      "callbacks": {
        "onBack": "() -> Void",
        "onError": "(CometChatException) -> Void",
        "onAiChatHistoryClicked": "() -> Void",
        "onAiNewChatClicked": "() -> Void"
      },
      "visibility": {
        "hideBackButton": { "type": "Bool", "default": false },
        "hideUserStatus": { "type": "Bool", "default": false },
        "hideVideoCallButton": { "type": "Bool", "default": false },
        "hideVoiceCallButton": { "type": "Bool", "default": false },
        "hideNewChatButton": { "type": "Bool", "default": false },
        "hideChatHistoryButton": { "type": "Bool", "default": false },
        "disableTyping": { "type": "Bool", "default": false }
      },
      "style": {
        "avatarStyle": { "type": "AvatarStyle", "default": "AvatarStyle()" },
        "statusIndicatorStyle": { "type": "StatusIndicatorStyle", "default": "StatusIndicatorStyle()" },
        "typingIndicatorStyle": { "type": "TypingIndicatorStyle", "default": "TypingIndicatorStyle()" }
      },
      "formatting": {
        "dateTimeFormatter": { "type": "CometChatDateTimeFormatter?", "default": "nil" }
      },
      "viewSlots": {
        "listItemView": "(User?, Group?) -> UIView",
        "leadingView": "(User?, Group?) -> UIView",
        "titleView": "(User?, Group?) -> UIView",
        "subtitleView": "(User?, Group?) -> UIView",
        "trailView": "(User?, Group?) -> UIView"
      }
    },
    "methods": {
      "connection": {
        "connect()": "Establishes WebSocket connection for real-time updates",
        "disconnect()": "Disconnects WebSocket connection"
      },
      "menuCustomization": {
        "set(options:)": "((User?, Group?) -> [CometChatMessageHeaderOption])? - Sets custom menu options"
      }
    },
    "events": [],
    "sdkListeners": [
      "onUserOnline",
      "onUserOffline",
      "onTypingStarted",
      "onTypingEnded"
    ],
    "compositionExample": {
      "description": "MessageHeader is typically used within CometChatMessages at the top of the chat screen",
      "components": ["CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
      "flow": "User views header → sees recipient info → taps back to return to conversations"
    },
    "types": {}
  }
  ```
</Accordion>

| Field     | Value                    |
| --------- | ------------------------ |
| Component | `CometChatMessageHeader` |
| Package   | `CometChatUIKitSwift`    |
| Inherits  | `UIView`                 |

***

## Where It Fits

`CometChatMessageHeader` displays the recipient's information at the top of the chat screen. It's typically used within `CometChatMessages` alongside `CometChatMessageList` and `CometChatMessageComposer`.

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

class ChatViewController: UIViewController {
    
    private var messageHeader: CometChatMessageHeader!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMessageHeader()
    }
    
    private func setupMessageHeader(for user: User) {
        messageHeader = CometChatMessageHeader()
        messageHeader.set(user: user)
        
        // Handle back button
        messageHeader.set(onBack: { [weak self] in
            self?.navigationController?.popViewController(animated: true)
        })
        
        view.addSubview(messageHeader)
    }
}
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/wpH0oTjPapnxuXny/images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png?fit=max&auto=format&n=wpH0oTjPapnxuXny&q=85&s=0bfbcecb645bf542dbf0bb7633df8bb7" alt="CometChatMessageHeader showing user avatar, name, online status, and call buttons in the navigation bar" width="1280" height="240" data-path="images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png" />
</Frame>

***

## Minimal Render

```swift lines theme={null}
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()
messageHeader.set(user: user)
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/wpH0oTjPapnxuXny/images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png?fit=max&auto=format&n=wpH0oTjPapnxuXny&q=85&s=0bfbcecb645bf542dbf0bb7633df8bb7" alt="CometChatMessageHeader showing minimal render with user details and default styling" width="1280" height="240" data-path="images/cdbdc9b3-message-header-cd5bd3b233f9e340571a62cc0e32f3f5.png" />
</Frame>

***

## Actions and Events

### Callback Props

#### onBack

Fires when the back button is pressed. Use this for custom navigation handling.

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

messageHeader.set(onBack: { [weak self] in
    self?.navigationController?.popViewController(animated: true)
})
```

#### onError

Fires when an error occurs.

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

messageHeader.set(onError: { error in
    print("Error: \(error.errorDescription)")
})
```

### Actions Reference

| Method          | Description                           | Example                    |
| --------------- | ------------------------------------- | -------------------------- |
| `set(onBack:)`  | Triggered when back button is pressed | Custom navigation          |
| `set(onError:)` | Triggered when an error occurs        | Show error alert           |
| `set(user:)`    | Sets the user to display              | Configure header for user  |
| `set(group:)`   | Sets the group to display             | Configure header for group |

### SDK Events (Real-Time, Automatic)

| SDK Listener      | Internal behavior                   |
| ----------------- | ----------------------------------- |
| `onUserOnline`    | Updates status indicator to online  |
| `onUserOffline`   | Updates status indicator to offline |
| `onTypingStarted` | Shows typing indicator in subtitle  |
| `onTypingEnded`   | Hides typing indicator              |

***

## Custom View Slots

| Slot           | Signature                   | Replaces                  |
| -------------- | --------------------------- | ------------------------- |
| `listItemView` | `(User?, Group?) -> UIView` | Entire header content     |
| `leadingView`  | `(User?, Group?) -> UIView` | Avatar / left section     |
| `titleView`    | `(User?, Group?) -> UIView` | Name / title text         |
| `subtitleView` | `(User?, Group?) -> UIView` | Status / subtitle text    |
| `trailView`    | `(User?, Group?) -> UIView` | Right side (call buttons) |

### listItemView

Replace the entire header content with a custom view.

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(listItemView: { user, group in
    let customView = CustomHeaderView()
    customView.configure(user: user, group: group)
    return customView
})
```

You can create a `CustomHeaderView` as a custom `UIView`:

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

class CustomHeaderView: UIView {
    
    private let backButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: "chevron.left"), for: .normal)
        button.tintColor = .black
        return button
    }()
    
    private let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = 18
        imageView.clipsToBounds = true
        imageView.backgroundColor = .lightGray
        return imageView
    }()
    
    private let nameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
        label.textColor = .black
        return label
    }()
    
    private let statusLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = .gray
        return label
    }()
    
    private let videoCallButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: "video.fill"), for: .normal)
        button.tintColor = .black
        return button
    }()
    
    private let callButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: "phone.fill"), 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)
        ])
    }
    
    func configure(user: User?, group: Group?) {
        nameLabel.text = user?.name ?? group?.name ?? "Chat"
        if let user = user {
            statusLabel.text = user.status == .online ? "Online" : "Offline"
        } else if let group = group {
            statusLabel.text = "\(group.membersCount) members"
        }
    }
}
```

### leadingView

Customize the leading view (avatar area) of the header.

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(leadingView: { user, group in
    let view = CustomLeadingView()
    return view
})
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/tZ9icCqOV58QJidg/images/e6fad16f-headerLeadng-6f55e63eb8a291dfe2a06771801f2337.png?fit=max&auto=format&n=tZ9icCqOV58QJidg&q=85&s=f5eed22a7b04d9eace9ceca480042775" alt="CometChatMessageHeader with custom leadingView showing avatar with Admin badge overlay" width="1280" height="240" data-path="images/e6fad16f-headerLeadng-6f55e63eb8a291dfe2a06771801f2337.png" />
</Frame>

You can create a `CustomLeadingView` as a custom `UIView`:

```swift lines 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
        imageView.image = UIImage(systemName: "person.fill")
        return imageView
    }()

    private let badgeLabel: UILabel = {
        let label = UILabel()
        label.text = "Admin"
        label.font = UIFont.systemFont(ofSize: 10, weight: .bold)
        label.textColor = .white
        label.backgroundColor = .orange
        label.textAlignment = .center
        label.layer.cornerRadius = 6
        label.clipsToBounds = true
        return label
    }()

    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(badgeLabel)

        profileImageView.translatesAutoresizingMaskIntoConstraints = false
        badgeLabel.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),

            badgeLabel.trailingAnchor.constraint(equalTo: profileImageView.trailingAnchor),
            badgeLabel.bottomAnchor.constraint(equalTo: profileImageView.bottomAnchor),
            badgeLabel.widthAnchor.constraint(equalToConstant: 40),
            badgeLabel.heightAnchor.constraint(equalToConstant: 12)
        ])
    }
}
```

### titleView

Customize the title view of the header.

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(titleView: { user, group in
    let view = CustomTitleView()
    return view
})
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/Vsd_l5VyiAINqcQj/images/77d20b8c-headerTitle-20200a0eddfa0c9f2337abb9511a9671.png?fit=max&auto=format&n=Vsd_l5VyiAINqcQj&q=85&s=26cbeed3ed894527b8508a8e9fbc90de" alt="CometChatMessageHeader with custom titleView showing group name with Public badge" width="1280" height="240" data-path="images/77d20b8c-headerTitle-20200a0eddfa0c9f2337abb9511a9671.png" />
</Frame>

You can create a `CustomTitleView` as a custom `UIView`:

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

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)
        ])
    }
}
```

### subtitleView

Customize the subtitle area (status, typing indicator).

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(subtitleView: { user, group in
    let label = UILabel()
    label.font = UIFont.systemFont(ofSize: 13)
    label.textColor = UIColor.secondaryLabel
    
    if let user = user {
        label.text = user.status == .online ? "🟢 Online" : "⚫ Offline"
    } else if let group = group {
        label.text = "\(group.membersCount) members"
    }
    
    return label
})
```

### trailView

Customize the right side of the header (call buttons, etc.).

```swift lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(trailView: { user, group in
    let view = CustomTrailView()
    return view
})
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/Vsd_l5VyiAINqcQj/images/7ae625d7-headerTrail-b0c07329c262e97434036abff2c0132d.png?fit=max&auto=format&n=Vsd_l5VyiAINqcQj&q=85&s=cab92e32a57041172917ae1faadde392" alt="CometChatMessageHeader with custom trailView showing video call, voice call, and bookmark buttons" width="1280" height="240" data-path="images/7ae625d7-headerTrail-b0c07329c262e97434036abff2c0132d.png" />
</Frame>

You can create a `CustomTrailView` as a custom `UIView`:

```swift lines 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: "bookmark.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, bookMarkButton])
        buttonsStack.axis = .horizontal
        buttonsStack.spacing = 16
        buttonsStack.distribution = .fillEqually

        addSubview(buttonsStack)
        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)
        ])
    }
}
```

***

## Styling

### Style Hierarchy

1. Global styles (`CometChatMessageHeader.style`) apply to all instances
2. Instance styles override global for specific instances

### Global Level Styling

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

// Apply global styles that affect all CometChatMessageHeader instances
CometChatMessageHeader.style.backgroundColor = UIColor.systemBackground
CometChatMessageHeader.style.titleTextColor = UIColor.label
CometChatMessageHeader.style.titleTextFont = UIFont.systemFont(ofSize: 17, weight: .semibold)
CometChatMessageHeader.style.subtitleTextColor = UIColor.secondaryLabel
CometChatMessageHeader.style.subtitleTextFont = UIFont.systemFont(ofSize: 13)
CometChatMessageHeader.style.backButtonImageTintColor = UIColor.systemBlue

// Custom avatar style
let avatarStyle = AvatarStyle()
avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 20)
CometChatMessageHeader.style.avatarStyle = avatarStyle
```

### Instance Level Styling

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

// Create a custom style for a specific instance
var customStyle = MessageHeaderStyle()
customStyle.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
customStyle.titleTextColor = UIColor.darkGray
customStyle.titleTextFont = UIFont.systemFont(ofSize: 18, weight: .bold)
customStyle.subtitleTextColor = UIColor.gray

let messageHeader = CometChatMessageHeader()
messageHeader.style = customStyle
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-card-builder/U1KbQ0VSXjjiH44y/images/54a6e640-message-header-style-d4203b4eece8507a4e5750d88e7fa913.png?fit=max&auto=format&n=U1KbQ0VSXjjiH44y&q=85&s=5bfe01c4e3aec8795d2546513414a501" alt="CometChatMessageHeader with custom instance styling showing modified background color and text appearance" width="1280" height="240" data-path="images/54a6e640-message-header-style-d4203b4eece8507a4e5750d88e7fa913.png" />
</Frame>

### Key Style Properties

| Property                                    | Type                    | Default                               | Description                                   |
| ------------------------------------------- | ----------------------- | ------------------------------------- | --------------------------------------------- |
| `backgroundColor`                           | `UIColor`               | `CometChatTheme.backgroundColor01`    | Background color                              |
| `borderWidth`                               | `CGFloat`               | `0`                                   | Border width                                  |
| `borderColor`                               | `UIColor`               | `.clear`                              | Border color                                  |
| `cornerRadius`                              | `CometChatCornerStyle?` | `nil`                                 | Corner radius                                 |
| `titleTextColor`                            | `UIColor`               | `CometChatTheme.textColorPrimary`     | Title text color                              |
| `titleTextFont`                             | `UIFont`                | `CometChatTypography.Heading4.medium` | Title font                                    |
| `subtitleTextColor`                         | `UIColor`               | `CometChatTheme.textColorSecondary`   | Subtitle text color                           |
| `subtitleTextFont`                          | `UIFont`                | `CometChatTypography.Body.regular`    | Subtitle font                                 |
| `backButtonImageTintColor`                  | `UIColor`               | `CometChatTheme.iconColorPrimary`     | Back button tint                              |
| `backButtonIcon`                            | `UIImage?`              | System chevron                        | Back button icon                              |
| `privateGroupBadgeImageTintColor`           | `UIColor`               | `CometChatTheme.iconColorSecondary`   | Private group badge tint                      |
| `passwordProtectedGroupBadgeImageTintColor` | `UIColor`               | `CometChatTheme.iconColorSecondary`   | Password group badge tint                     |
| `avatarStyle`                               | `AvatarStyle`           | `AvatarStyle()`                       | Avatar customization                          |
| `statusIndicatorStyle`                      | `StatusIndicatorStyle`  | `StatusIndicatorStyle()`              | Online/offline status indicator customization |
| `typingIndicatorStyle`                      | `TypingIndicatorStyle`  | `TypingIndicatorStyle()`              | Typing indicator customization                |

### Customization Matrix

| What to change      | Where     | Property/API                                 | Example                                     |
| ------------------- | --------- | -------------------------------------------- | ------------------------------------------- |
| Background color    | Style     | `backgroundColor`                            | `UIColor.systemBackground`                  |
| Title appearance    | Style     | `titleTextColor`, `titleTextFont`            | Custom colors and fonts                     |
| Subtitle appearance | Style     | `subtitleTextColor`, `subtitleTextFont`      | Custom colors and fonts                     |
| Back button         | Style     | `backButtonIcon`, `backButtonImageTintColor` | Custom icon and color                       |
| Avatar look         | Style     | `avatarStyle`                                | `AvatarStyle()` with custom radius          |
| Status indicator    | Style     | `statusIndicatorStyle`                       | `StatusIndicatorStyle()` with custom colors |
| Typing indicator    | Style     | `typingIndicatorStyle`                       | `TypingIndicatorStyle()` with custom font   |
| Hide back button    | Property  | `hideBackButton`                             | `header.hideBackButton = true`              |
| Hide status         | Property  | `hideUserStatus`                             | `header.hideUserStatus = true`              |
| Disable typing      | Property  | `disableTyping`                              | `header.disableTyping = true`               |
| Hide AI buttons     | Property  | `hideNewChatButton`, `hideChatHistoryButton` | `header.hideNewChatButton = true`           |
| Custom subtitle     | View Slot | `set(subtitleView:)`                         | See Custom View Slots                       |
| Custom menu options | Method    | `set(options:)`                              | See Menu Customization                      |

***

## Connection Management

Manually control the WebSocket connection for the message header.

### connect()

Establishes the WebSocket connection for real-time updates. Use this when you need to manually reconnect after disconnecting.

```swift lines theme={null}
@discardableResult
public func connect() -> Self
```

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

// Manually connect to receive real-time updates
messageHeader.connect()
```

### disconnect()

Disconnects the WebSocket connection. Use this when you want to temporarily stop receiving real-time updates, such as when the view is not visible.

```swift lines theme={null}
@discardableResult
public func disconnect() -> Self
```

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

class ChatViewController: UIViewController {
    
    private var messageHeader: CometChatMessageHeader!
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        messageHeader.disconnect()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        messageHeader.connect()
    }
}
```

***

## Menu Customization

### set(options:)

Sets custom menu options for the message header. These options appear in the header's menu (typically accessed via a more button or long press).

```swift lines theme={null}
@discardableResult
public func set(options: ((_ user: User?, _ group: Group?) -> [CometChatMessageHeaderOption])?) -> Self
```

| Parameter | Type                                                   | Description                                                                      |
| --------- | ------------------------------------------------------ | -------------------------------------------------------------------------------- |
| `options` | `((User?, Group?) -> [CometChatMessageHeaderOption])?` | Closure that returns an array of menu options based on the current user or group |

```swift lines theme={null}
import CometChatUIKitSwift
import CometChatSDK

let messageHeader = CometChatMessageHeader()

messageHeader.set(options: { user, group in
    var options = [CometChatMessageHeaderOption]()
    
    // Add a custom "View Profile" option
    let viewProfileOption = CometChatMessageHeaderOption(
        id: "view_profile",
        title: "View Profile",
        icon: UIImage(systemName: "person.circle")
    ) { user, group in
        // Handle view profile action
        print("View profile tapped")
    }
    options.append(viewProfileOption)
    
    // Add a custom "Mute Notifications" option
    let muteOption = CometChatMessageHeaderOption(
        id: "mute_notifications",
        title: "Mute Notifications",
        icon: UIImage(systemName: "bell.slash")
    ) { user, group in
        // Handle mute action
        print("Mute notifications tapped")
    }
    options.append(muteOption)
    
    return options
})
```

***

## Props

All props are optional. Sorted alphabetically.

### avatarStyle

Customizes the appearance of the avatar in the message header.

|         |                 |
| ------- | --------------- |
| Type    | `AvatarStyle`   |
| Default | `AvatarStyle()` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

let avatarStyle = AvatarStyle()
avatarStyle.backgroundColor = UIColor.systemBlue
avatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 20)
avatarStyle.borderWidth = 2
avatarStyle.borderColor = UIColor.white

messageHeader.set(avatarStyle: avatarStyle)
```

### dateTimeFormatter

Custom formatter for date/time display in the message header (e.g., "Last seen at...").

|         |                               |
| ------- | ----------------------------- |
| Type    | `CometChatDateTimeFormatter?` |
| Default | `nil`                         |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

let dateTimeFormatter = CometChatDateTimeFormatter()
dateTimeFormatter.todayFormat = "h:mm a"
dateTimeFormatter.yesterdayFormat = "'Yesterday at' h:mm a"
dateTimeFormatter.otherFormat = "MMM d, yyyy"

messageHeader.dateTimeFormatter = dateTimeFormatter
```

### disableTyping

Disables typing indicators in the message header.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()
messageHeader.disableTyping = true
```

### hideBackButton

Hides the back button in the header.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

### hideChatHistoryButton

Hides the AI chat history button in the header.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()
messageHeader.hideChatHistoryButton = true
```

### hideNewChatButton

Hides the AI new chat button in the header.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()
messageHeader.hideNewChatButton = true
```

### hideUserStatus

Hides the user status (online/offline/last active).

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

### hideVideoCallButton

Hides the video call button.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

### hideVoiceCallButton

Hides the voice call button.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

### onAiChatHistoryClicked

Callback triggered when the AI chat history button is clicked.

|         |                 |
| ------- | --------------- |
| Type    | `(() -> Void)?` |
| Default | `nil`           |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

messageHeader.set(onAiChatHistoryClicked: { [weak self] in
    // Handle AI chat history button click
    self?.presentAiChatHistory()
})
```

### onAiNewChatClicked

Callback triggered when the AI new chat button is clicked.

|         |                 |
| ------- | --------------- |
| Type    | `(() -> Void)?` |
| Default | `nil`           |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

messageHeader.set(onAiNewChatClicked: { [weak self] in
    // Handle AI new chat button click
    self?.startNewAiChat()
})
```

### statusIndicatorStyle

Customizes the appearance of the online/offline status indicator.

|         |                          |
| ------- | ------------------------ |
| Type    | `StatusIndicatorStyle`   |
| Default | `StatusIndicatorStyle()` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

let statusIndicatorStyle = StatusIndicatorStyle()
statusIndicatorStyle.backgroundColor = UIColor.systemGreen
statusIndicatorStyle.borderWidth = 2
statusIndicatorStyle.borderColor = UIColor.white
statusIndicatorStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 6)

messageHeader.set(statusIndicatorStyle: statusIndicatorStyle)
```

### typingIndicatorStyle

Customizes the appearance of the typing indicator in the message header subtitle.

|         |                          |
| ------- | ------------------------ |
| Type    | `TypingIndicatorStyle`   |
| Default | `TypingIndicatorStyle()` |

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

let typingIndicatorStyle = TypingIndicatorStyle()
typingIndicatorStyle.textColor = UIColor.systemGray
typingIndicatorStyle.textFont = UIFont.italicSystemFont(ofSize: 13)

messageHeader.set(typingIndicatorStyle: typingIndicatorStyle)
```

***

## Events

The MessageHeader component does not emit any global UI events.

***

## Date Time Formatter

Customize how timestamps appear in the message header (e.g., "Last seen at...") using the `CometChatDateTimeFormatter`.

### Global Level Formatting

```swift lines theme={null}
import CometChatUIKitSwift

// Customize time format for last seen
CometChatMessageHeader.dateTimeFormatter.time = { timestamp in
    let date = Date(timeIntervalSince1970: TimeInterval(timestamp))
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mm a"
    return "Last seen at " + formatter.string(from: date)
}

// Customize today format
CometChatMessageHeader.dateTimeFormatter.today = { timestamp in
    let date = Date(timeIntervalSince1970: TimeInterval(timestamp))
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mm a"
    return "Last seen today at " + formatter.string(from: date)
}

// Customize yesterday format
CometChatMessageHeader.dateTimeFormatter.yesterday = { timestamp in
    let date = Date(timeIntervalSince1970: TimeInterval(timestamp))
    let formatter = DateFormatter()
    formatter.dateFormat = "h:mm a"
    return "Last seen yesterday at " + formatter.string(from: date)
}
```

### Instance Level Formatting

```swift lines theme={null}
import CometChatUIKitSwift

let messageHeader = CometChatMessageHeader()

messageHeader.dateTimeFormatter.otherDay = { timestamp in
    let date = Date(timeIntervalSince1970: TimeInterval(timestamp))
    let formatter = DateFormatter()
    formatter.dateFormat = "MMM d, yyyy"
    return "Last seen on " + formatter.string(from: date)
}
```

### Available Formatters

| Formatter   | Purpose                    | Default Format        |
| ----------- | -------------------------- | --------------------- |
| `time`      | Standard time display      | `h:mm a`              |
| `today`     | Last seen today            | `Today at h:mm a`     |
| `yesterday` | Last seen yesterday        | `Yesterday at h:mm a` |
| `lastweek`  | Last seen within last week | Day name              |
| `otherDay`  | Last seen older dates      | `MMM d, yyyy`         |

***

## Common Patterns

### Hide call buttons

```swift lines theme={null}
let messageHeader = CometChatMessageHeader()
messageHeader.set(user: user)
messageHeader.hideVideoCallButton = true
messageHeader.hideVoiceCallButton = true
```

### Custom back button action

```swift lines theme={null}
let messageHeader = CometChatMessageHeader()
messageHeader.set(user: user)

messageHeader.set(onBack: { [weak self] in
    // Custom navigation logic
    self?.dismiss(animated: true)
})
```

### Custom subtitle with typing indicator

```swift lines theme={null}
let messageHeader = CometChatMessageHeader()
messageHeader.set(user: user)

messageHeader.set(subtitleView: { user, group in
    let label = UILabel()
    label.font = UIFont.systemFont(ofSize: 12)
    
    if let user = user {
        label.text = user.status == .online ? "Online" : "Offline"
        label.textColor = user.status == .online ? .systemGreen : .secondaryLabel
    }
    
    return label
})
```

### Minimal header

```swift lines theme={null}
let messageHeader = CometChatMessageHeader()
messageHeader.set(user: user)
messageHeader.hideBackButton = true
messageHeader.hideUserStatus = true
messageHeader.hideVideoCallButton = true
messageHeader.hideVoiceCallButton = true
```

***

## Related Components

* [Messages](/ui-kit/ios/message-list) - Parent component containing MessageHeader
* [Message List](/ui-kit/ios/message-list) - Display messages in a conversation
* [Message Composer](/ui-kit/ios/message-composer) - Send messages in a conversation
* [Conversations](/ui-kit/ios/conversations) - Navigate back to conversation list
