Skip to main content
The CometChatMessageComposer component enables users to write and send messages including text, images, videos, audio, files, and custom messages. It supports attachments, voice recording, stickers, mentions, and AI-powered features.
{
  "component": "CometChatMessageComposer",
  "package": "CometChatUIKitSwift",
  "import": "import CometChatUIKitSwift\nimport CometChatSDK",
  "description": "Enables users to compose and send messages with support for text, media, attachments, voice recording, stickers, mentions, and AI features.",
  "inherits": "UIView",
  "primaryOutput": {
    "callback": "onSendButtonClick",
    "type": "(BaseMessage) -> Void"
  },
  "props": {
    "data": {
      "user": {
        "type": "User?",
        "default": "nil",
        "note": "User for direct messaging"
      },
      "group": {
        "type": "Group?",
        "default": "nil",
        "note": "Group for group messaging"
      },
      "parentMessageId": {
        "type": "Int?",
        "default": "nil",
        "note": "Parent message ID for thread replies"
      }
    },
    "callbacks": {
      "onSendButtonClick": "(BaseMessage) -> Void",
      "onTextChanged": "(String) -> Void",
      "onError": "(CometChatException) -> Void"
    },
    "visibility": {
      "hideAttachmentButton": { "type": "Bool", "default": false },
      "hideVoiceRecordingButton": { "type": "Bool", "default": false },
      "hideStickersButton": { "type": "Bool", "default": false },
      "hideSendButton": { "type": "Bool", "default": false },
      "hideImageAttachmentOption": { "type": "Bool", "default": false },
      "hideVideoAttachmentOption": { "type": "Bool", "default": false },
      "hideAudioAttachmentOption": { "type": "Bool", "default": false },
      "hideFileAttachmentOption": { "type": "Bool", "default": false },
      "hidePollsOption": { "type": "Bool", "default": false },
      "hideCollaborativeDocumentOption": { "type": "Bool", "default": false },
      "hideCollaborativeWhiteboardOption": { "type": "Bool", "default": false }
    },
    "behavior": {
      "disableTypingEvents": { "type": "Bool", "default": false },
      "disableMentions": { "type": "Bool", "default": false },
      "disableSoundForMessages": { "type": "Bool", "default": false },
      "maxLine": { "type": "Int", "default": 5 }
    },
    "viewSlots": {
      "headerView": "(User?, Group?) -> UIView",
      "footerView": "(User?, Group?) -> UIView",
      "sendButtonView": "(User?, Group?) -> UIView",
      "attachmentOptions": "(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]"
    },
    "formatting": {
      "textFormatters": "[CometChatTextFormatter]"
    }
  },
  "events": [],
  "sdkListeners": [],
  "compositionExample": {
    "description": "MessageComposer is typically used within CometChatMessages alongside MessageHeader and MessageList",
    "components": ["CometChatMessageHeader", "CometChatMessageList", "CometChatMessageComposer"],
    "flow": "User types message → onTextChanged fires → User taps send → onSendButtonClick fires → Message sent"
  },
  "types": {
    "CometChatMessageComposerAction": {
      "id": "String",
      "text": "String",
      "startIcon": "UIImage?",
      "startIconTint": "UIColor?",
      "textColor": "UIColor?",
      "onActionClick": "() -> Void"
    }
  }
}

Where It Fits

CometChatMessageComposer is the input component for sending messages. It’s typically used within CometChatMessages alongside CometChatMessageHeader and CometChatMessageList.
import UIKit
import CometChatUIKitSwift
import CometChatSDK

class ChatViewController: UIViewController {
    
    private var messageComposer: CometChatMessageComposer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMessageComposer()
    }
    
    private func setupMessageComposer(for user: User) {
        messageComposer = CometChatMessageComposer()
        messageComposer.set(user: user)
        
        // Handle send button click
        messageComposer.set(onSendButtonClick: { [weak self] message in
            print("Message sent: \(message.id)")
        })
        
        // Handle text changes for typing indicators
        messageComposer.set(onTextChanged: { [weak self] text in
            print("User is typing: \(text)")
        })
        
        view.addSubview(messageComposer)
    }
}

Minimal Render

import CometChatUIKitSwift
import CometChatSDK

let messageComposer = CometChatMessageComposer()
messageComposer.set(user: user)

Actions and Events

Callback Props

onSendButtonClick

Fires when the send button is clicked. Use this to handle custom send actions.
import CometChatUIKitSwift
import CometChatSDK

let messageComposer = CometChatMessageComposer()

messageComposer.set(onSendButtonClick: { [weak self] message in
    guard let self = self else { return }
    print("Message sent with ID: \(message.id)")
})

onTextChanged

Fires when the user types in the composer. Use this for typing indicators or text validation.
import CometChatUIKitSwift

let messageComposer = CometChatMessageComposer()

messageComposer.set(onTextChanged: { [weak self] text in
    guard let self = self else { return }
    print("Current text: \(text)")
})

onError

Fires when an error occurs while sending a message.
import CometChatUIKitSwift

let messageComposer = CometChatMessageComposer()

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

Actions Reference

MethodDescriptionExample
set(onSendButtonClick:)Triggered when send button is clickedCustom send handling
set(onTextChanged:)Triggered when text changesTyping indicators
set(onError:)Triggered when an error occursShow error alert
set(user:)Sets the user for direct messagingConfigure recipient
set(group:)Sets the group for group messagingConfigure group
set(parentMessageId:)Sets parent message for thread repliesThread replies
setInitialComposerText(_:)Sets initial text in composerPre-fill message

Custom View Slots

SlotSignatureReplaces
headerView(User?, Group?) -> UIViewHeader above composer
footerView(User?, Group?) -> UIViewFooter below composer
sendButtonView(User?, Group?) -> UIViewSend button
attachmentOptions(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]Attachment menu options

headerView

Add a custom header above the composer.
import UIKit
import CometChatUIKitSwift

let messageComposer = CometChatMessageComposer()

messageComposer.set(headerView: { user, group in
    let view = CustomHeaderView()
    return view
})
You can create a CustomHeaderView as a custom UIView:
import UIKit

class CustomHeaderView: UIView {

    private let iconImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(systemName: "bell.slash.fill")
        imageView.tintColor = .purple
        imageView.contentMode = .scaleAspectFit
        return imageView
    }()

    private let messageLabel: UILabel = {
        let label = UILabel()
        label.text = "User has paused their notifications"
        label.textColor = .black
        label.font = UIFont.systemFont(ofSize: 14, weight: .medium)
        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() {
        backgroundColor = UIColor.purple.withAlphaComponent(0.1)
        layer.cornerRadius = 12

        addSubview(iconImageView)
        addSubview(messageLabel)

        iconImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            iconImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            iconImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
            iconImageView.widthAnchor.constraint(equalToConstant: 20),
            iconImageView.heightAnchor.constraint(equalToConstant: 20),

            messageLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: 8),
            messageLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            messageLabel.centerYAnchor.constraint(equalTo: centerYAnchor)
        ])
    }
}

sendButtonView

Replace the default send button with a custom view.
import UIKit
import CometChatUIKitSwift

let messageComposer = CometChatMessageComposer()

messageComposer.set(sendButtonView: { user, group in
    let button = UIButton(type: .system)
    button.setImage(UIImage(systemName: "paperplane.fill"), for: .normal)
    button.tintColor = UIColor.systemBlue
    button.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.1)
    button.layer.cornerRadius = 20
    return button
})

attachmentOptions

Customize the attachment menu options.
import UIKit
import CometChatUIKitSwift

let messageComposer = CometChatMessageComposer()

messageComposer.set(attachmentOptions: { user, group, controller in
    let photoAction = CometChatMessageComposerAction(
        id: "photo",
        text: "Photo",
        startIcon: UIImage(systemName: "photo"),
        startIconTint: UIColor.systemBlue,
        textColor: UIColor.label,
        onActionClick: {
            print("Photo selected")
        }
    )
    
    let cameraAction = CometChatMessageComposerAction(
        id: "camera",
        text: "Camera",
        startIcon: UIImage(systemName: "camera"),
        startIconTint: UIColor.systemGreen,
        textColor: UIColor.label,
        onActionClick: {
            print("Camera selected")
        }
    )
    
    let locationAction = CometChatMessageComposerAction(
        id: "location",
        text: "Location",
        startIcon: UIImage(systemName: "location"),
        startIconTint: UIColor.systemRed,
        textColor: UIColor.label,
        onActionClick: {
            print("Location selected")
        }
    )
    
    return [photoAction, cameraAction, locationAction]
})

Styling

Style Hierarchy

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

Global Level Styling

import UIKit
import CometChatUIKitSwift

// Apply global styles that affect all CometChatMessageComposer instances
CometChatMessageComposer.style.backgroundColor = UIColor.systemBackground
CometChatMessageComposer.style.activeSendButtonImageBackgroundColor = UIColor.systemBlue
CometChatMessageComposer.style.attachmentImageTint = UIColor.systemGray
CometChatMessageComposer.style.voiceRecordingImageTint = UIColor.systemGray
CometChatMessageComposer.style.stickerTint = UIColor.systemGray
CometChatMessageComposer.style.aiImageTint = UIColor.systemPurple

Instance Level Styling

import UIKit
import CometChatUIKitSwift

// Create a custom style for a specific instance
var customStyle = MessageComposerStyle()
customStyle.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
customStyle.activeSendButtonImageBackgroundColor = UIColor.systemOrange
customStyle.composeBoxBackgroundColor = UIColor.white
customStyle.composeBoxBorderColor = UIColor.systemGray4
customStyle.composeBoxBorderWidth = 1

let messageComposer = CometChatMessageComposer()
messageComposer.style = customStyle

Key Style Properties

PropertyTypeDefaultDescription
backgroundColorUIColorCometChatTheme.backgroundColor01Background color
borderWidthCGFloat0Border width
borderColorUIColor.clearBorder color
cornerRadiusCometChatCornerStyle?nilCorner radius
placeHolderTextFontUIFontCometChatTypography.Body.regularPlaceholder font
placeHolderTextColorUIColorCometChatTheme.textColorTertiaryPlaceholder color
textFiledColorUIColorCometChatTheme.textColorPrimaryInput text color
textFiledFontUIFontCometChatTypography.Body.regularInput text font
sendButtonImageUIImage?System send iconSend button icon
sendButtonImageTintUIColorCometChatTheme.whiteSend button tint
activeSendButtonImageBackgroundColorUIColorCometChatTheme.primaryColorActive send button background
inactiveSendButtonImageBackgroundColorUIColorCometChatTheme.neutralColor300Inactive send button background
composeBoxBackgroundColorUIColorCometChatTheme.backgroundColor01Compose box background
composeBoxBorderColorUIColorCometChatTheme.borderColorDefaultCompose box border color
composeBoxBorderWidthCGFloat1Compose box border width
attachmentImageUIImage?System plus iconAttachment button icon
attachmentImageTintUIColorCometChatTheme.iconColorSecondaryAttachment icon tint
voiceRecordingImageUIImage?System mic iconVoice recording icon
voiceRecordingImageTintUIColorCometChatTheme.iconColorSecondaryVoice recording tint

Customization Matrix

What to changeWhereProperty/APIExample
Background colorStylebackgroundColorUIColor.systemBackground
Send button colorStyleactiveSendButtonImageBackgroundColorUIColor.systemBlue
Input text styleStyletextFiledColor, textFiledFontCustom colors and fonts
Compose box lookStylecomposeBoxBackgroundColor, composeBoxBorderColorCustom styling
Attachment iconStyleattachmentImage, attachmentImageTintCustom icon
Hide attachmentPropertyhideAttachmentButtoncomposer.hideAttachmentButton = true
Hide voice recordingPropertyhideVoiceRecordingButtoncomposer.hideVoiceRecordingButton = true
Custom send buttonView Slotset(sendButtonView:)See Custom View Slots

Props

All props are optional. Sorted alphabetically.

disableMentions

Disables the @mention feature in the composer.
TypeBool
Defaultfalse

disableSoundForMessages

Disables sound when sending messages.
TypeBool
Defaultfalse

disableTypingEvents

Disables sending typing indicators when the user types.
TypeBool
Defaultfalse

hideAttachmentButton

Hides the attachment button.
TypeBool
Defaultfalse

hideAudioAttachmentOption

Hides the audio attachment option.
TypeBool
Defaultfalse

hideCollaborativeDocumentOption

Hides the collaborative document option.
TypeBool
Defaultfalse

hideCollaborativeWhiteboardOption

Hides the collaborative whiteboard option.
TypeBool
Defaultfalse

hideFileAttachmentOption

Hides the file attachment option.
TypeBool
Defaultfalse

hideImageAttachmentOption

Hides the image attachment option.
TypeBool
Defaultfalse

hidePollsOption

Hides the polls option.
TypeBool
Defaultfalse

hideSendButton

Hides the send button.
TypeBool
Defaultfalse

hideStickersButton

Hides the stickers button.
TypeBool
Defaultfalse

hideVideoAttachmentOption

Hides the video attachment option.
TypeBool
Defaultfalse

hideVoiceRecordingButton

Hides the voice recording button.
TypeBool
Defaultfalse

maxLine

Sets the maximum number of lines for the composer input before scrolling.
TypeInt
Default5

textFormatters

Array of text formatters for customizing text display (e.g., mentions).
Type[CometChatTextFormatter]
Default[]

Events

The MessageComposer component does not emit any global UI events.

Troubleshooting

IssueSolution
Send button not workingEnsure user or group is set on the composer
Attachments not showingCheck that attachment options are not hidden
Voice recording not workingVerify microphone permissions are granted
Mentions not workingEnsure disableMentions is not set to true
Typing indicators not sentCheck that disableTypingEvents is not set to true