Skip to main content
Version: v5

Message Composer

Overview

MessageComposer is a Component that enables users to write and send a variety of messages, including text, image, video, and custom messages.

Image

MessageComposer is comprised of the following Base Components:

Base ComponentsDescription
MessageInputThis provides a basic layout for the contents of this component, such as the TextField and buttons
ActionSheetThe ActionSheet component presents a list of options in either a list or grid mode, depending on the user's preference

Usage

Integration

The following code snippet illustrates how you can directly incorporate the MessageComposer component into your file.

// syntax for set(user: User)
let messageComposer = CometChatMessageComposer()
messageComposer.set(user: user)
messageComposer.set(parentMessageId: 20)

Actions

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.

1. onSendButtonClick

The set(onSendButtonClick:) event gets activated when the send message button is clicked. The following code snippet Overrides the action of the send button in CometChatMessageComposer.

messageComposer.set(onSendButtonClick: { message in
// return custom action here
})

2. OnTextChanged:

The set(onTextChanged:) event gets activated when the user starts typing in message composer. This will return the text entered by the user.

messageComposer.set(onTextChanged: { error in
// Handle action
})


3. SetOnError

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

messageComposer.set(onError { error in
// Override on error
})


Filters

MessageComposer component does not have any available filters.


Events

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 MessageComposer Component does not emit any events of its own.


Customization

To fit your app's design requirements, you can customize the appearance of the MessageComposer 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. MessageComposer Style

To customize the styling, you can apply the MessageComposerStyle to the MessageComposer component.

Global level styling

CometChatMessageComposer.style.activeSendButtonImageBackgroundColor = UIColor(hex: "#F76808")
CometChatMessageComposer.style.attachmentImageTint = UIColor(hex: "#F76808")
CometChatMessageComposer.style.voiceRecordingImageTint = UIColor(hex: "#F76808")
CometChatMessageComposer.style.stickerTint = UIColor(hex: "#F76808")
CometChatMessageComposer.style.aiImageTint = UIColor(hex: "#F76808")

Instance level styling

let customComposerStyle = MessageComposerStyle()
customComposerStyle.activeSendButtonImageBackgroundColor = UIColor(hex: "#F76808")
customComposerStyle.attachmentImageTint = UIColor(hex: "#F76808")
customComposerStyle.voiceRecordingImageTint = UIColor(hex: "#F76808")
customComposerStyle.stickerTint = UIColor(hex: "#F76808")
customComposerStyle.aiImageTint = UIColor(hex: "#F76808")

let messageComposer = CometChatMessageComposer()
messageComposer.style = customComposerStyle
Image

The following properties are exposed by MessageComposerStyle:

PropertyDescriptionCode
Placeholder Text FontFont for the placeholder text in the input field.CometChatMessageComposer.style.placeHolderTextFont = CometChatTypography.Body.regular
Placeholder Text ColorColor for the placeholder text in the input field.CometChatMessageComposer.style.placeHolderTextColor = CometChatTheme.textColorTertiary
Text Field ColorText color for the input field.CometChatMessageComposer.style.textFiledColor = CometChatTheme.textColorPrimary
Text Field FontFont for the input field text.CometChatMessageComposer.style.textFiledFont = CometChatTypography.Body.regular
Background ColorBackground color with dynamic support for light and dark mode.CometChatMessageComposer.style.backgroundColor = UIColor.dynamicColor(lightModeColor: ..., darkModeColor: ...)
Corner RadiusCorner radius for the composer.CometChatMessageComposer.style.cornerRadius = CometChatCornerStyle?
Border WidthBorder width for the composer.CometChatMessageComposer.style.borderWidth = 0
Border ColorBorder color for the composer.CometChatMessageComposer.style.borderColor = .clear
Send Button ImageIcon for the send button.CometChatMessageComposer.style.sendButtonImage = UIImage(named: "custom-send")
Send Button Tint ColorTint color for the send button image.CometChatMessageComposer.style.sendButtonImageTint = CometChatTheme.white
Active Send Button Background ColorBackground color for the send button when active.CometChatMessageComposer.style.activeSendButtonImageBackgroundColor = CometChatTheme.primaryColor
Inactive Send Button Background ColorBackground color for the send button when inactive.CometChatMessageComposer.style.inactiveSendButtonImageBackgroundColor = CometChatTheme.neutralColor300
Compose Box Background ColorBackground color for the compose box.CometChatMessageComposer.style.composeBoxBackgroundColor = CometChatTheme.backgroundColor01
Compose Box Border ColorBorder color for the compose box.CometChatMessageComposer.style.composeBoxBorderColor = CometChatTheme.borderColorDefault
Compose Box Border WidthBorder width for the compose box.CometChatMessageComposer.style.composeBoxBorderWidth = 1
Compose Box Corner RadiusCorner radius for the compose box.CometChatMessageComposer.style.composerBoxCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r2)
Compose Box Separator ColorColor for the separator in the compose box.CometChatMessageComposer.style.composerSeparatorColor = CometChatTheme.borderColorLight
Attachment ImageIcon for the attachment button.CometChatMessageComposer.style.attachmentImage = UIImage(systemName: "plus.circle")
Attachment Image TintTint color for the attachment image.CometChatMessageComposer.style.attachmentImageTint = CometChatTheme.iconColorSecondary
Voice Recording ImageIcon for the voice recording button.CometChatMessageComposer.style.voiceRecordingImage = UIImage(systemName: "mic")?.withRenderingMode(.alwaysTemplate)
Voice Recording Image TintTint color for the voice recording image.CometChatMessageComposer.style.voiceRecordingImageTint = CometChatTheme.iconColorSecondary
AI ImageIcon for the AI button.CometChatMessageComposer.style.aiImage = UIImage(named: "ai-image")
AI Image TintTint color for the AI image.CometChatMessageComposer.style.aiImageTint = CometChatTheme.iconColorSecondary
Sticker ImageIcon for the sticker button.CometChatMessageComposer.style.stickerImage = UIImage(named: "sticker-image")
Sticker Image TintTint color for the sticker image.CometChatMessageComposer.style.stickerTint = CometChatTheme.iconColorSecondary
Edit Preview Title FontFont for the title in the edit preview.CometChatMessageComposer.style.editPreviewTitleTextFont = CometChatTypography.Body.regular
Edit Preview Message FontFont for the message text in the edit preview.CometChatMessageComposer.style.editPreviewMessageTextFont = CometChatTypography.Caption1.regular
Edit Preview Title ColorText color for the title in the edit preview.CometChatMessageComposer.style.editPreviewTitleTextColor = CometChatTheme.textColorPrimary
Edit Preview Message ColorText color for the message in the edit preview.CometChatMessageComposer.style.editPreviewMessageTextColor = CometChatTheme.textColorSecondary
Edit Preview Background ColorBackground color for the edit preview.CometChatMessageComposer.style.editPreviewBackgroundColor = CometChatTheme.backgroundColor03
Edit Preview Corner RadiusCorner radius for the edit preview.CometChatMessageComposer.style.editPreviewCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r1)
Edit Preview Border ColorBorder color for the edit preview.CometChatMessageComposer.style.editPreviewBorderColor = .clear
Edit Preview Border WidthBorder width for the edit preview.CometChatMessageComposer.style.editPreviewBorderWidth = 0
Edit Preview Close IconIcon for closing the edit preview.CometChatMessageComposer.style.editPreviewCloseIcon = UIImage(systemName: "xmark")?.withRenderingMode(.alwaysTemplate)
Edit Preview Close Icon TintTint color for the close icon in the edit preview.CometChatMessageComposer.style.editPreviewCloseIconTint = CometChatTheme.iconColorPrimary
Info IconIcon for the info button.CometChatMessageComposer.style.infoIcon = UIImage(systemName: "info.circle")
Info Icon TintTint color for the info icon.CometChatMessageComposer.style.infoIconTint = CometChatTheme.errorColor
Info Text ColorText color for the info text.CometChatMessageComposer.style.infoTextColor = CometChatTheme.errorColor
Info Text FontFont for the info text.CometChatMessageComposer.style.infoTextFont = CometChatTypography.Caption1.regular
Info Separator ColorColor for the separator in the info section.CometChatMessageComposer.style.infoSeparatorColor = CometChatTheme.borderColorLight
Info Background ColorBackground color for the info section.CometChatMessageComposer.style.infoBackgroundColor = CometChatTheme.backgroundColor02
Info Corner RadiusCorner radius for the info section.CometChatMessageComposer.style.infoCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r1)
Info Border ColorBorder color for the info section.CometChatMessageComposer.style.infoBorderColor = .clear
Info Border WidthBorder width for the info section.CometChatMessageComposer.style.infoBorderWidth = 0
2. MediaRecorder Style

To customize the media recording styling, you can apply the MediaRecorderStyle to the MessageComposer component. For more details, please refer to MediaRecorder styles.

Global level styling

CometChatMessageComposer.mediaRecorderStyle.deleteButtonCornerRadius = .init(cornerRadius: 8)
CometChatMessageComposer.mediaRecorderStyle.pauseButtonCornerRadius = .init(cornerRadius: 8)
CometChatMessageComposer.mediaRecorderStyle.stopButtonCornerRadius = .init(cornerRadius: 8)
CometChatMessageComposer.mediaRecorderStyle.recordingButtonCornerRadius = .init(cornerRadius: 8)
CometChatMessageComposer.mediaRecorderStyle.recordingButtonBackgroundColor = UIColor(hex: "#F44649")

Instance level styling

var mediaRecorderStyle = MediaRecorderStyle()
mediaRecorderStyle.deleteButtonCornerRadius = .init(cornerRadius: 8)
mediaRecorderStyle.pauseButtonCornerRadius = .init(cornerRadius: 8)
mediaRecorderStyle.stopButtonCornerRadius = .init(cornerRadius: 8)
mediaRecorderStyle.recordingButtonCornerRadius = .init(cornerRadius: 8)
mediaRecorderStyle.recordingButtonBackgroundColor = UIColor(hex: "#F44649")

let messageComposer = CometChatMessageComposer()
messageComposer.mediaRecorderStyle = mediaRecorderStyle
Image

The following properties are exposed by Media Recorder Style:

PropertyDescriptionCode
backgroundColorSets the background color of the media recorder.mediaRecorderStyle.backgroundColor: UIColor = CometChatTheme.backgroundColor01
borderWidthDefines the width of the border for the media recorder.mediaRecorderStyle.borderWidth: CGFloat = 1
borderColorSpecifies the border color of the media recorder.mediaRecorderStyle.borderColor: UIColor = CometChatTheme.borderColorLight
cornerRadiusConfigures the corner radius of the media recorder.mediaRecorderStyle.cornerRadius: CometChatCornerStyle? = nil
recordingButtonBackgroundColorSets the background color of the recording button.mediaRecorderStyle.recordingButtonBackgroundColor: UIColor = CometChatTheme.iconColorHighlight
recordingButtonCornerRadiusConfigures the corner radius of the recording button.mediaRecorderStyle.recordingButtonCornerRadius: CometChatCornerStyle? = nil
recordingButtonBorderWidthSets the border width of the recording button.mediaRecorderStyle.recordingButtonBorderWidth: CGFloat = 0
recordingButtonBorderColorSets the border color of the recording button.mediaRecorderStyle.recordingButtonBorderColor: UIColor = .clear
recordingButtonImageTintColorSpecifies the tint color of the recording button image.mediaRecorderStyle.recordingButtonImageTintColor: UIColor = CometChatTheme.white
recordingButtonImageThe image displayed on the recording button.mediaRecorderStyle.recordingButtonImage: UIImage = UIImage(systemName: "mic.fill") ?? UIImage()
deleteButtonBackgroundColorSets the background color of the delete button.mediaRecorderStyle.deleteButtonBackgroundColor: UIColor = CometChatTheme.backgroundColor01
deleteButtonImageTintColorSpecifies the tint color of the delete button image.mediaRecorderStyle.deleteButtonImageTintColor: UIColor = CometChatTheme.iconColorSecondary
deleteButtonImageThe image displayed on the delete button.mediaRecorderStyle.deleteButtonImage: UIImage = UIImage(systemName: "trash.fill") ?? UIImage()
deleteButtonCornerRadiusConfigures the corner radius of the delete button.mediaRecorderStyle.deleteButtonCornerRadius: CometChatCornerStyle? = nil
deleteButtonBorderWidthSets the border width of the delete button.mediaRecorderStyle.deleteButtonBorderWidth: CGFloat = 1
deleteButtonBorderColorSpecifies the border color of the delete button.mediaRecorderStyle.deleteButtonBorderColor: UIColor = CometChatTheme.borderColorLight
3. AI Options Style

To customize the media recording styling, you can apply the AIOptionsStyle to the MessageComposer component. For more details, please refer to MediaRecorder styles.

Global level styling

CometChatMessageComposer.aiOptionsStyle.backgroundColor = UIColor(hex: "#FFF9F5")
CometChatMessageComposer.aiOptionsStyle.textColor = .black
CometChatMessageComposer.aiOptionsStyle.aiImageTintColor = UIColor(hex: "#F76808")

Instance level styling

var aIOptionsStyle = AIOptionsStyle()
aIOptionsStyle.backgroundColor = UIColor(hex: "#FFF9F5")
aIOptionsStyle.textColor = .black
aIOptionsStyle.aiImageTintColor = UIColor(hex: "#F76808")

let messageComposer = CometChatMessageComposer()
messageComposer.aiOptionsStyle = aIOptionsStyle
Image

The following properties are exposed by AI Options Style:

PropertyDescriptionCode
errorViewTextFontSpecifies the font used for the text in the error view.aIOptionsStyle.errorViewTextFont: UIFont?
errorViewTextColorSets the color of the text in the error view.aIOptionsStyle.errorViewTextColor: UIColor?
emptyViewTextFontSpecifies the font used for the text in the empty view.aIOptionsStyle.emptyViewTextFont: UIFont?
emptyViewTextColorSets the color of the text in the empty view.aIOptionsStyle.emptyViewTextColor: UIColor?
aiImageTintColorConfigures the tint color for AI-related images.aIOptionsStyle.aiImageTintColor: UIColor = CometChatTheme.iconColorHighlight
textColorSets the color of the text.aIOptionsStyle.textColor: UIColor = CometChatTheme.textColorPrimary
textFontSpecifies the font for the text.aIOptionsStyle.textFont: UIFont = CometChatTypography.Heading4.regular
backgroundColorSets the background color.aIOptionsStyle.backgroundColor: UIColor = CometChatTheme.backgroundColor01
borderWidthSets the width of the border.aIOptionsStyle.borderWidth: CGFloat = 0
borderColorSets the color of the border.aIOptionsStyle.borderColor: UIColor = .clear
cornerRadiusConfigures the corner radius of the view.aIOptionsStyle.cornerRadius: CometChatCornerStyle? = nil

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 set maximum lines text area will show before scrolling in the composer, edit a message, add header view and footer view to the composer, etc.

Below is a list of customizations along with corresponding code snippets message composer offers

PropertyDescriptionCode
setInitialComposerTextSets the initial text in the composer when it loads.setInitialComposerText("Hello")
disableTypingEventsDisables sending typing indicators when the user types.disableTypingEvents = true
disableMentionsDisables the mention feature in the composer.disableMentions = true
hideImageAttachmentOptionHides the option to attach images.hideImageAttachmentOption = true
hideVideoAttachmentOptionHides the option to attach videos.hideVideoAttachmentOption = true
hideAudioAttachmentOptionHides the option to attach audio files.hideAudioAttachmentOption = true
hideFileAttachmentOptionHides the option to attach files.hideFileAttachmentOption = true
hidePollsOptionHides the option to create polls.hidePollsOption = true
hideCollaborativeDocumentOptionHides the option for collaborative documents.hideCollaborativeDocumentOption = true
hideCollaborativeWhiteboardOptionHides the option for collaborative whiteboards.hideCollaborativeWhiteboardOption = true
hideAttachmentButtonHides the attachment button in the composer.hideAttachmentButton = true
hideVoiceRecordingButtonHides the voice recording button.hideVoiceRecordingButton = true
hideStickersButtonHides the stickers button.hideStickersButton = true
hideSendButtonHides the send button.hideSendButton = true
setUserSets the user for direct messaging.set(user: User)
setGroupSets the group for group messaging.set(group: Group)
setParentMessageIdSets the parent message ID for replying in a thread.set(parentMessageId: 12345)
setMaxLineSets the maximum number of lines for the composer input.set(maxLine: 3)
setCustomSoundForMessagesSets a custom sound for sending messages.set(customSoundForMessages: URL?)
disableSoundForMessagesDisables sound while sending messages.disableSoundForMessages = true

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.

AttachmentOptions

By using set(attachmentOptions:), you can set a list of custom MessageComposerActions for the MessageComposer Component. This will override the existing list of CometChatMessageComposerAction.

let messageComposer = CometChatMessageComposer()
messageComposer.set(attachmentOptions: { user, group, controller in
return [CometChatMessageComposerAction]
})

Demonstration

Image

In this example, we are overriding the existing MessageComposerActions List with Capture Photo actions.

let messageComposer  = CometChatMessageComposer()
messageComposer.setAttachmentOptions { user, group, controller in
let customComposerAction1 = CometChatMessageComposerAction(
id: "customAction1",
text: "Custom Option 1",
startIcon: UIImage(systemName: "play_circle"),
startIconTint: .black,
textColor: .black,
onActionClick: {
print("Custom Action 1 clicked!")
}
)
let customComposerAction2 = CometChatMessageComposerAction(
id: "customAction2",
text: "Custom Option 2",
startIcon: UIImage(systemName: "add_box"),
startIconTint: .black,
textColor: .black,
onActionClick: {
print("Custom Action 2 clicked!")
}
)
let customComposerAction3 = CometChatMessageComposerAction(
id: "customAction3",
text: "Custom Option 3",
startIcon: UIImage(systemName: "change_circle"),
startIconTint: .black,
textColor: .black,
onActionClick: {
print("Custom Action 3 clicked!")
}
)
let customComposerAction4 = CometChatMessageComposerAction(
id: "customAction4",
text: "Custom Option 4",
startIcon: UIImage(systemName: "sunny"),
startIconTint: .black,
textColor: .black,
onActionClick: {
print("Custom Action 4 clicked!")
}
)

return [customComposerAction1 , customComposerAction2, customComposerAction3, customComposerAction4]
}

SendButtonView

By using set(sendButtonView:), you can set a custom send button for the MessageComposer Component.

let messageComposer = CustomSendButton()
messageComposer.set(sendButtonView: { user, group in
let view = CustomSendButton()
return view
})

Demonstration

Image
import UIKit

class CustomSendButton: UIView {

private let playButton: UIButton = {
let button = UIButton(type: .system)
let playImage = UIImage(systemName: "play.fill")?.withRenderingMode(.alwaysTemplate)
button.setImage(playImage, for: .normal)
button.tintColor = .purple
button.backgroundColor = .clear
button.addTarget(self, action: #selector(playButtonTapped), for: .touchUpInside)
return button
}()

var onPlayTapped: (() -> Void)? // Closure to handle button tap

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

playButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
playButton.centerXAnchor.constraint(equalTo: centerXAnchor),
playButton.centerYAnchor.constraint(equalTo: centerYAnchor),
playButton.widthAnchor.constraint(equalToConstant: 30),
playButton.heightAnchor.constraint(equalToConstant: 30)
])
}

@objc private func playButtonTapped() {
onPlayTapped?() // Executes the closure when tapped
}
}



HeaderView

By using set(headerView:), you can set a custom header view for the MessageComposer Component.

let messageComposer = CometChatMessageComposer()
messageComposer.set(headerView: { user, group in
let view = CustomHeaderView()
return view
})

Demonstration

Image
import UIKit

class CustomHeaderView: UIView {

private let iconImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(systemName: "bell.slash.fill") // Replace with the actual image if needed
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)
])
}
}


SetTextFormatters

Assigns the list of text formatters. If the provided list is not null, it sets the list. Otherwise, it assigns the default text formatters retrieved from the data source. To configure the existing Mentions look and feel check out CometChatMentionsFormatter

Example

let composerTextStyle = MentionTextStyle()
.set(textBackgroundColor: .white)
.set(textColor: UIColor.black)
.set(textFont: UIFont.systemFont(ofSize: 18, weight: .heavy))
.set(loggedInUserTextColor: UIColor.systemTeal)
.set(loggedInUserTextFont: UIFont.systemFont(ofSize: 18, weight: .bold))

let customMentionFormatter = CometChatMentionsFormatter()
.set(composerTextStyle: composerTextStyle)

let messageComposerConfiguration = MessageComposerConfiguration()
.set(textFormatter: [customMentionFormatter])

let cometChatMessages = CometChatMessages()
.set(user: user)
.set(messageComposerConfiguration: messageComposerConfiguration)
info

Ensure to pass and present cometChatMessages. If a navigation controller is already in use, utilize the pushViewController function instead of directly presenting the view controller.