diff --git a/calls/ios/ringing.mdx b/calls/ios/ringing.mdx
index d07d14957..710b4b56a 100644
--- a/calls/ios/ringing.mdx
+++ b/calls/ios/ringing.mdx
@@ -18,17 +18,17 @@ The ringing flow involves two SDKs working together:
```mermaid
sequenceDiagram
- participant Caller
- participant ChatSDK
- participant Receiver
- participant CallsSDK
-
- Caller->>ChatSDK: initiateCall()
- ChatSDK->>Receiver: onIncomingCallReceived
- Receiver->>ChatSDK: acceptCall()
- ChatSDK-->>Caller: onOutgoingCallAccepted
- Caller->>CallsSDK: joinSession()
- Receiver->>CallsSDK: joinSession()
+participant Caller
+participant ChatSDK
+participant Receiver
+participant CallsSDK
+
+Caller->>ChatSDK: initiateCall()
+ChatSDK->>Receiver: onIncomingCallReceived
+Receiver->>ChatSDK: acceptCall()
+ChatSDK-->>Caller: onOutgoingCallAccepted
+Caller->>CallsSDK: joinSession()
+Receiver->>CallsSDK: joinSession()
```
## Initiate a Call
@@ -58,12 +58,9 @@ NSString *receiverID = @"USER_ID";
CometChatReceiverType receiverType = CometChatReceiverTypeUser;
CometChatCallType callType = CometChatCallTypeVideo;
-Call *call = [[Call alloc] initWithReceiverId:receiverID
- callType:callType
- receiverType:receiverType];
+Call *call = [[Call alloc] initWithReceiverId:receiverID callType:callType receiverType:receiverType];
-[CometChat initiateCallWithCall:call
- onSuccess:^(Call * call) {
+[CometChat initiateCallWithCall:call onSuccess:^(Call * call) {
NSLog(@"Call initiated: %@", call.sessionID);
// Show outgoing call UI
} onError:^(CometChatException * error) {
@@ -79,6 +76,59 @@ Call *call = [[Call alloc] initWithReceiverId:receiverID
| `receiverType` | ReceiverType | `.user` or `.group` |
| `callType` | CallType | `.video` or `.audio` |
+## Call Timeout
+
+By default, if the receiver does not answer within **45 seconds**, the call is automatically marked as `unanswered` and the caller receives the `onOutgoingCallRejected` callback. You can customize this duration by passing a `timeout` parameter (in seconds) when initiating the call.
+
+
+
+```swift
+let receiverID = "USER_ID"
+let receiverType: CometChat.ReceiverType = .user
+let callType: CometChat.CallType = .video
+
+let call = Call(receiverId: receiverID, callType: callType, receiverType: receiverType)
+
+// Set a custom timeout of 30 seconds
+CometChat.initiateCall(call: call, timeout: 30, onSuccess: { call in
+ print("Call initiated: \(call?.sessionID ?? "")")
+}, onError: { error in
+ print("Call initiation failed: \(error?.errorDescription ?? "")")
+})
+```
+
+
+```objectivec
+NSString *receiverID = @"USER_ID";
+CometChatReceiverType receiverType = CometChatReceiverTypeUser;
+CometChatCallType callType = CometChatCallTypeVideo;
+
+Call *call = [[Call alloc] initWithReceiverId:receiverID callType:callType receiverType:receiverType];
+
+// Set a custom timeout of 30 seconds
+[CometChat initiateCallWithCall:call timeout:30 onSuccess:^(Call * call) {
+ NSLog(@"Call initiated: %@", call.sessionID);
+} onError:^(CometChatException * error) {
+ NSLog(@"Call initiation failed: %@", error.errorDescription);
+}];
+```
+
+
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `call` | Call | The call object with receiver and call type details |
+| `timeout` | Double | Time in seconds to wait before marking the call as unanswered. Defaults to `45`. Non-integer values are truncated (e.g., `30.7` becomes `30`). Values ≤ 0 fall back to the default `45` seconds. |
+
+When the timeout expires without the call being accepted, the SDK automatically:
+1. Sends an `unanswered` call status to the server.
+2. Triggers the `onOutgoingCallRejected` callback on the caller's side with the call status set to `.unanswered`.
+3. Cleans up the call session.
+
+
+If the call is accepted, rejected, or cancelled before the timeout expires, the timer is automatically stopped and the timeout has no effect.
+
+
## Listen for Incoming Calls
Register a call listener to receive incoming call notifications:
@@ -92,7 +142,7 @@ CometChat.addCallListener(listenerID, self)
// Implement CometChatCallDelegate
extension CallViewController: CometChatCallDelegate {
-
+
func onIncomingCallReceived(incomingCall: Call?, error: CometChatException?) {
guard let call = incomingCall else { return }
print("Incoming call from: \(call.callInitiator?.name ?? "")")
@@ -128,32 +178,27 @@ NSString *listenerID = @"UNIQUE_LISTENER_ID";
[CometChat addCallListener:listenerID delegate:self];
// Implement CometChatCallDelegate
-- (void)onIncomingCallReceivedWithIncomingCall:(Call *)incomingCall
- error:(CometChatException *)error {
+- (void)onIncomingCallReceivedWithIncomingCall:(Call *)incomingCall error:(CometChatException *)error {
NSLog(@"Incoming call from: %@", incomingCall.callInitiator.name);
// Show incoming call UI with accept/reject options
}
-- (void)onOutgoingCallAcceptedWithAcceptedCall:(Call *)acceptedCall
- error:(CometChatException *)error {
+- (void)onOutgoingCallAcceptedWithAcceptedCall:(Call *)acceptedCall error:(CometChatException *)error {
NSLog(@"Call accepted, joining session...");
[self joinCallSessionWithSessionId:acceptedCall.sessionID];
}
-- (void)onOutgoingCallRejectedWithRejectedCall:(Call *)rejectedCall
- error:(CometChatException *)error {
+- (void)onOutgoingCallRejectedWithRejectedCall:(Call *)rejectedCall error:(CometChatException *)error {
NSLog(@"Call rejected");
// Dismiss outgoing call UI
}
-- (void)onIncomingCallCancelledWithCancelledCall:(Call *)cancelledCall
- error:(CometChatException *)error {
+- (void)onIncomingCallCancelledWithCancelledCall:(Call *)cancelledCall error:(CometChatException *)error {
NSLog(@"Incoming call cancelled");
// Dismiss incoming call UI
}
-- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall
- error:(CometChatException *)error {
+- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall error:(CometChatException *)error {
NSLog(@"Call ended");
}
```
@@ -164,12 +209,13 @@ NSString *listenerID = @"UNIQUE_LISTENER_ID";
|----------|-------------|
| `onIncomingCallReceived` | A new incoming call is received |
| `onOutgoingCallAccepted` | The receiver accepted your outgoing call |
-| `onOutgoingCallRejected` | The receiver rejected your outgoing call |
+| `onOutgoingCallRejected` | The receiver rejected your outgoing call, or the call timed out as unanswered |
| `onIncomingCallCancelled` | The caller cancelled the incoming call |
| `onCallEndedMessageReceived` | The call has ended |
Remember to remove the call listener when it's no longer needed to prevent memory leaks:
+
```swift
CometChat.removeCallListener(listenerID)
```
@@ -195,8 +241,7 @@ func acceptIncomingCall(sessionId: String) {
```objectivec
- (void)acceptIncomingCallWithSessionId:(NSString *)sessionId {
- [CometChat acceptCallWithSessionID:sessionId
- onSuccess:^(Call * call) {
+ [CometChat acceptCallWithSessionID:sessionId onSuccess:^(Call * call) {
NSLog(@"Call accepted");
[self joinCallSessionWithSessionId:call.sessionID];
} onError:^(CometChatException * error) {
@@ -229,9 +274,7 @@ func rejectIncomingCall(sessionId: String) {
```objectivec
- (void)rejectIncomingCallWithSessionId:(NSString *)sessionId {
- [CometChat rejectCallWithSessionID:sessionId
- status:CometChatCallStatusRejected
- onSuccess:^(Call * call) {
+ [CometChat rejectCallWithSessionID:sessionId status:CometChatCallStatusRejected onSuccess:^(Call * call) {
NSLog(@"Call rejected");
// Dismiss incoming call UI
} onError:^(CometChatException * error) {
@@ -264,9 +307,7 @@ func cancelOutgoingCall(sessionId: String) {
```objectivec
- (void)cancelOutgoingCallWithSessionId:(NSString *)sessionId {
- [CometChat rejectCallWithSessionID:sessionId
- status:CometChatCallStatusCancelled
- onSuccess:^(Call * call) {
+ [CometChat rejectCallWithSessionID:sessionId status:CometChatCallStatusCancelled onSuccess:^(Call * call) {
NSLog(@"Call cancelled");
// Dismiss outgoing call UI
} onError:^(CometChatException * error) {
@@ -311,13 +352,13 @@ func joinCallSession(sessionId: String) {
build];
[CometChatCalls joinSessionWithSessionID:sessionId
- callSetting:sessionSettings
- container:self.callViewContainer
- onSuccess:^(NSString * message) {
- NSLog(@"Joined call session");
- } onError:^(CometChatCallException * error) {
- NSLog(@"Failed to join: %@", error.errorDescription);
- }];
+ callSetting:sessionSettings
+ container:self.callViewContainer
+ onSuccess:^(NSString * message) {
+ NSLog(@"Joined call session");
+ } onError:^(CometChatCallException * error) {
+ NSLog(@"Failed to join: %@", error.errorDescription);
+ }];
}
```
@@ -333,15 +374,15 @@ Always call `CometChat.endCall()` when ending a call. This notifies the other pa
```mermaid
sequenceDiagram
- participant User
- participant CallsSDK
- participant ChatSDK
- participant OtherParticipant
-
- User->>CallsSDK: leaveSession()
- User->>ChatSDK: endCall(sessionId)
- ChatSDK->>OtherParticipant: onCallEndedMessageReceived
- OtherParticipant->>CallsSDK: leaveSession()
+participant User
+participant CallsSDK
+participant ChatSDK
+participant OtherParticipant
+
+User->>CallsSDK: leaveSession()
+User->>ChatSDK: endCall(sessionId)
+ChatSDK->>OtherParticipant: onCallEndedMessageReceived
+OtherParticipant->>CallsSDK: leaveSession()
```
When using the default call UI, listen for the end call button click using `ButtonClickListener` and call `endCall()`:
@@ -350,18 +391,17 @@ When using the default call UI, listen for the end call button click using `Butt
```swift
class CallViewController: UIViewController, ButtonClickListener {
-
var currentSessionId: String = ""
-
+
override func viewDidLoad() {
super.viewDidLoad()
CallSession.shared.addButtonClickListener(self)
}
-
+
func onLeaveSessionButtonClicked() {
endCall(sessionId: currentSessionId)
}
-
+
func endCall(sessionId: String) {
// 1. Leave the call session (Calls SDK)
CallSession.shared.leaveSession()
@@ -375,7 +415,7 @@ class CallViewController: UIViewController, ButtonClickListener {
self.navigationController?.popViewController(animated: true)
})
}
-
+
// Other ButtonClickListener callbacks...
}
```
@@ -402,8 +442,7 @@ class CallViewController: UIViewController, ButtonClickListener {
[[CallSession shared] leaveSession];
// 2. Notify other participants (Chat SDK)
- [CometChat endCallWithSessionID:sessionId
- onSuccess:^(Call * call) {
+ [CometChat endCallWithSessionID:sessionId onSuccess:^(Call * call) {
NSLog(@"Call ended successfully");
[self.navigationController popViewControllerAnimated:YES];
} onError:^(CometChatException * error) {
@@ -430,8 +469,7 @@ func onCallEndedMessageReceived(endedCall: Call?, error: CometChatException?) {
```objectivec
-- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall
- error:(CometChatException *)error {
+- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall error:(CometChatException *)error {
[[CallSession shared] leaveSession];
[self.navigationController popViewControllerAnimated:YES];
}
@@ -450,4 +488,4 @@ func onCallEndedMessageReceived(endedCall: Call?, error: CometChatException?) {
| `cancelled` | Caller cancelled before receiver answered |
| `ended` | Call ended normally |
| `missed` | Receiver didn't answer in time |
-| `unanswered` | Call was not answered |
+| `unanswered` | Call was not answered within the timeout duration |
diff --git a/images/compact-message-composer.png b/images/compact-message-composer.png
new file mode 100644
index 000000000..46b0f52c5
Binary files /dev/null and b/images/compact-message-composer.png differ
diff --git a/ui-kit/ios/message-composer.mdx b/ui-kit/ios/message-composer.mdx
index 524bd6220..488bfdbab 100644
--- a/ui-kit/ios/message-composer.mdx
+++ b/ui-kit/ios/message-composer.mdx
@@ -1,547 +1,851 @@
---
title: "Message Composer"
-description: "Enable users to write and send text, media, and custom messages"
---
-
-```json
-{
- "component": "CometChatMessageComposer",
- "package": "CometChatUIKitSwift",
- "import": "import CometChatUIKitSwift\nimport CometChatSDK",
- "inherits": "UIView",
- "description": "Rich text input for composing and sending text, media, attachments, mentions, voice notes, and custom messages.",
- "props": {
- "data": {
- "user": "User? - recipient user for direct messaging",
- "group": "Group? - recipient group for group messaging",
- "parentMessageId": "Int? - parent message ID for thread replies"
- },
- "callbacks": {
- "onSendButtonClick": "(BaseMessage) -> Void",
- "onTextChangedListener": "(String) -> Void",
- "onError": "(CometChatException) -> Void"
- },
- "visibility": {
- "hideAttachmentButton": "Bool (default: false)",
- "hideVoiceRecordingButton": "Bool (default: false)",
- "hideStickersButton": "Bool (default: false)",
- "hideSendButton": "Bool (default: false)",
- "hideAIButton": "Bool (default: false)",
- "hideHeaderView": "Bool (default: false)",
- "hideFooterView": "Bool (default: false)"
- },
- "behavior": {
- "disableTypingEvents": "Bool (default: false)",
- "disableMentions": "Bool (default: false)",
- "placeholderText": "String (default: 'Type a message...')"
- },
- "viewSlots": {
- "headerView": "(User?, Group?) -> UIView",
- "footerView": "(User?, Group?) -> UIView",
- "sendButtonView": "(User?, Group?) -> UIView",
- "auxillaryButtonView": "(User?, Group?) -> UIView",
- "attachmentOptions": "(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]"
- }
- },
- "methods": {
- "set(user:)": "Sets recipient user",
- "set(group:)": "Sets recipient group",
- "set(parentMessageId:)": "Sets parent message for threads",
- "setInitialComposerText(_:)": "Pre-fills composer text",
- "set(textFormatter:)": "Sets custom text formatter",
- "setDisableMentionAll(_:)": "Disables @all mentions",
- "setMentionAllLabel(_:_:)": "Customizes @all label"
- },
- "styling": {
- "globalStyle": "CometChatMessageComposer.style",
- "instanceStyle": "MessageComposerStyle",
- "subStyles": ["MediaRecorderStyle", "AttachmentSheetStyle", "SuggestionsStyle", "AIOptionsStyle", "MentionStyle"]
- }
-}
-```
-
+## Overview
-| Field | Value |
-|-------|-------|
-| Component | `CometChatMessageComposer` |
-| Package | `CometChatUIKitSwift` |
-| Inherits | `UIView` |
-
-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.
+MessageComposer is a [Component](/ui-kit/ios/components-overview#components) that enables users to write and send a variety of messages, including text, image, video, and custom messages.
-
+
----
+MessageComposer is comprised of the following [Base Components](/ui-kit/ios/components-overview#base-components):
-## Where It Fits
+| Base Components | Description |
+| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
+| [MessageInput](/ui-kit/ios/message-input) | This provides a basic layout for the contents of this component, such as the TextField and buttons |
+| [ActionSheet](/ui-kit/ios/action-sheet) | The ActionSheet component presents a list of options in either a list or grid mode, depending on the user's preference |
-`CometChatMessageComposer` provides a rich text input with attachment, emoji, voice recording, sticker, and send controls. Wire it alongside `CometChatMessageHeader` and `CometChatMessageList` to build a standard chat view.
+## Usage
-```swift lines
-import UIKit
-import CometChatUIKitSwift
-import CometChatSDK
+### Integration
-class ChatViewController: UIViewController {
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- CometChat.getUser(UID: "uid") { user in
- DispatchQueue.main.async {
- let header = CometChatMessageHeader()
- header.set(user: user)
-
- let messageList = CometChatMessageList()
- messageList.set(user: user)
-
- let composer = CometChatMessageComposer()
- composer.set(user: user)
-
- // Add to view hierarchy and layout
- }
- } onError: { error in
- print("Error: \(error?.errorDescription ?? "")")
- }
- }
-}
+The following code snippet illustrates how you can directly incorporate the MessageComposer component into your file.
+
+```csharp
+// syntax for set(user: User)
+let messageComposer = CometChatMessageComposer()
+messageComposer.set(user: user)
+messageComposer.set(parentMessageId: 20)
```
-
-
-
+### 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.
-## Minimal Render
+##### 1. onSendButtonClick
-```swift lines
-import CometChatUIKitSwift
+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.
-let composer = CometChatMessageComposer()
-composer.set(user: user)
+
+
+```swift
+messageComposer.set(onSendButtonClick: { message in
+// return custom action here
+})
```
+
+
-
-
-
-
----
+***
-## Actions and Events
+##### 2. OnTextChanged:
-### Callback Props
+The `set(onTextChanged:)` event gets activated when the user starts typing in message composer. This will return the text entered by the user.
-#### onSendButtonClick
+
+
+```swift
+messageComposer.set(onTextChanged: { error in
+// Handle action
+})
+```
+
+
-Fires when the send button is clicked. Overrides the default send behavior.
+***
-```swift lines
-import CometChatUIKitSwift
+##### 3. SetOnError
-let composer = CometChatMessageComposer()
-composer.set(user: user)
+This method proves helpful when a user needs to customize the action taken upon encountering an error in CometChatMessageComposer.
-composer.set(onSendButtonClick: { message in
- print("Custom send: \(message.id)")
+
+
+```swift
+messageComposer.set(onError { error in
+// Override on error
})
```
+
+
-#### onTextChangedListener
+***
-Fires as the user types in the composer input.
+### Filters
-```swift lines
-import CometChatUIKitSwift
+MessageComposer component does not have any available filters.
-let composer = CometChatMessageComposer()
-composer.set(user: user)
+***
-composer.set(onTextChangedListener: { text in
- print("Text changed: \(text)")
-})
-```
+### Events
-#### onError
+[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.
-Fires on internal errors.
+The MessageComposer Component does not emit any events of its own.
-```swift lines
-import CometChatUIKitSwift
+***
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-
-composer.set(onError: { error in
- print("Composer error: \(error.errorDescription)")
-})
-```
+## Customization
-### SDK Events (Real-Time, Automatic)
+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.
-The component internally handles typing indicators and message sending. No manual SDK listener attachment needed.
+### 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.
-## Custom View Slots
+##### 1. MessageComposer Style
-| Slot | Signature | Replaces |
-|------|-----------|----------|
-| `headerView` | `(User?, Group?) -> UIView` | Area above the composer input |
-| `footerView` | `(User?, Group?) -> UIView` | Area below the composer input |
-| `sendButtonView` | `(User?, Group?) -> UIView` | Send button |
-| `auxillaryButtonView` | `(User?, Group?) -> UIView` | Sticker and AI button area |
-| `attachmentOptions` | `(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]` | Default attachment options list |
+To customize the styling, you can apply the `MessageComposerStyle` to the `MessageComposer` component.
-### headerView
+**Global level styling**
-Custom view above the composer input.
+
+
+```swift
+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**
+
+
+
+```swift
+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
+```
+
+
-
+
-```swift lines
-import UIKit
-import CometChatUIKitSwift
+The following properties are exposed by MessageComposerStyle:
+
+| **Property** | **Description** | **Code** |
+| ----------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
+| **Placeholder Text Font** | Font for the placeholder text in the input field. | `CometChatMessageComposer.style.placeHolderTextFont = CometChatTypography.Body.regular` |
+| **Placeholder Text Color** | Color for the placeholder text in the input field. | `CometChatMessageComposer.style.placeHolderTextColor = CometChatTheme.textColorTertiary` |
+| **Text Field Color** | Text color for the input field. | `CometChatMessageComposer.style.textFiledColor = CometChatTheme.textColorPrimary` |
+| **Text Field Font** | Font for the input field text. | `CometChatMessageComposer.style.textFiledFont = CometChatTypography.Body.regular` |
+| **Background Color** | Background color with dynamic support for light and dark mode. | `CometChatMessageComposer.style.backgroundColor = UIColor.dynamicColor(lightModeColor: ..., darkModeColor: ...)` |
+| **Corner Radius** | Corner radius for the composer. | `CometChatMessageComposer.style.cornerRadius = CometChatCornerStyle?` |
+| **Border Width** | Border width for the composer. | `CometChatMessageComposer.style.borderWidth = 0` |
+| **Border Color** | Border color for the composer. | `CometChatMessageComposer.style.borderColor = .clear` |
+| **Send Button Image** | Icon for the send button. | `CometChatMessageComposer.style.sendButtonImage = UIImage(named: "custom-send")` |
+| **Send Button Tint Color** | Tint color for the send button image. | `CometChatMessageComposer.style.sendButtonImageTint = CometChatTheme.white` |
+| **Active Send Button Background Color** | Background color for the send button when active. | `CometChatMessageComposer.style.activeSendButtonImageBackgroundColor = CometChatTheme.primaryColor` |
+| **Inactive Send Button Background Color** | Background color for the send button when inactive. | `CometChatMessageComposer.style.inactiveSendButtonImageBackgroundColor = CometChatTheme.neutralColor300` |
+| **Compose Box Background Color** | Background color for the compose box. | `CometChatMessageComposer.style.composeBoxBackgroundColor = CometChatTheme.backgroundColor01` |
+| **Compose Box Border Color** | Border color for the compose box. | `CometChatMessageComposer.style.composeBoxBorderColor = CometChatTheme.borderColorDefault` |
+| **Compose Box Border Width** | Border width for the compose box. | `CometChatMessageComposer.style.composeBoxBorderWidth = 1` |
+| **Compose Box Corner Radius** | Corner radius for the compose box. | `CometChatMessageComposer.style.composerBoxCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r2)` |
+| **Compose Box Separator Color** | Color for the separator in the compose box. | `CometChatMessageComposer.style.composerSeparatorColor = CometChatTheme.borderColorLight` |
+| **Attachment Image** | Icon for the attachment button. | `CometChatMessageComposer.style.attachmentImage = UIImage(systemName: "plus.circle")` |
+| **Attachment Image Tint** | Tint color for the attachment image. | `CometChatMessageComposer.style.attachmentImageTint = CometChatTheme.iconColorSecondary` |
+| **Voice Recording Image** | Icon for the voice recording button. | `CometChatMessageComposer.style.voiceRecordingImage = UIImage(systemName: "mic")?.withRenderingMode(.alwaysTemplate)` |
+| **Voice Recording Image Tint** | Tint color for the voice recording image. | `CometChatMessageComposer.style.voiceRecordingImageTint = CometChatTheme.iconColorSecondary` |
+| **AI Image** | Icon for the AI button. | `CometChatMessageComposer.style.aiImage = UIImage(named: "ai-image")` |
+| **AI Image Tint** | Tint color for the AI image. | `CometChatMessageComposer.style.aiImageTint = CometChatTheme.iconColorSecondary` |
+| **Sticker Image** | Icon for the sticker button. | `CometChatMessageComposer.style.stickerImage = UIImage(named: "sticker-image")` |
+| **Sticker Image Tint** | Tint color for the sticker image. | `CometChatMessageComposer.style.stickerTint = CometChatTheme.iconColorSecondary` |
+| **Edit Preview Title Font** | Font for the title in the edit preview. | `CometChatMessageComposer.style.editPreviewTitleTextFont = CometChatTypography.Body.regular` |
+| **Edit Preview Message Font** | Font for the message text in the edit preview. | `CometChatMessageComposer.style.editPreviewMessageTextFont = CometChatTypography.Caption1.regular` |
+| **Edit Preview Title Color** | Text color for the title in the edit preview. | `CometChatMessageComposer.style.editPreviewTitleTextColor = CometChatTheme.textColorPrimary` |
+| **Edit Preview Message Color** | Text color for the message in the edit preview. | `CometChatMessageComposer.style.editPreviewMessageTextColor = CometChatTheme.textColorSecondary` |
+| **Edit Preview Background Color** | Background color for the edit preview. | `CometChatMessageComposer.style.editPreviewBackgroundColor = CometChatTheme.backgroundColor03` |
+| **Edit Preview Corner Radius** | Corner radius for the edit preview. | `CometChatMessageComposer.style.editPreviewCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r1)` |
+| **Edit Preview Border Color** | Border color for the edit preview. | `CometChatMessageComposer.style.editPreviewBorderColor = .clear` |
+| **Edit Preview Border Width** | Border width for the edit preview. | `CometChatMessageComposer.style.editPreviewBorderWidth = 0` |
+| **Edit Preview Close Icon** | Icon for closing the edit preview. | `CometChatMessageComposer.style.editPreviewCloseIcon = UIImage(systemName: "xmark")?.withRenderingMode(.alwaysTemplate)` |
+| **Edit Preview Close Icon Tint** | Tint color for the close icon in the edit preview. | `CometChatMessageComposer.style.editPreviewCloseIconTint = CometChatTheme.iconColorPrimary` |
+| **Info Icon** | Icon for the info button. | `CometChatMessageComposer.style.infoIcon = UIImage(systemName: "info.circle")` |
+| **Info Icon Tint** | Tint color for the info icon. | `CometChatMessageComposer.style.infoIconTint = CometChatTheme.errorColor` |
+| **Info Text Color** | Text color for the info text. | `CometChatMessageComposer.style.infoTextColor = CometChatTheme.errorColor` |
+| **Info Text Font** | Font for the info text. | `CometChatMessageComposer.style.infoTextFont = CometChatTypography.Caption1.regular` |
+| **Info Separator Color** | Color for the separator in the info section. | `CometChatMessageComposer.style.infoSeparatorColor = CometChatTheme.borderColorLight` |
+| **Info Background Color** | Background color for the info section. | `CometChatMessageComposer.style.infoBackgroundColor = CometChatTheme.backgroundColor02` |
+| **Info Corner Radius** | Corner radius for the info section. | `CometChatMessageComposer.style.infoCornerRadius = .init(cornerRadius: CometChatSpacing.Radius.r1)` |
+| **Info Border Color** | Border color for the info section. | `CometChatMessageComposer.style.infoBorderColor = .clear` |
+| **Info Border Width** | Border 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](/ui-kit/ios/component-styling#media-recorder) styles.
+
+**Global level styling**
+
+
+
+```swift
+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**
+
+
+
+```swift
+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
+```
+
+
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-
-composer.set(headerView: { user, group in
- let view = UIView()
- view.backgroundColor = UIColor.purple.withAlphaComponent(0.1)
-
- let label = UILabel()
- label.text = "User has paused their notifications"
- label.font = UIFont.systemFont(ofSize: 14)
- view.addSubview(label)
-
- return view
-})
+
+
+
+
+The following properties are exposed by Media Recorder Style:
+
+| **Property** | **Description** | **Code** |
+| ---------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
+| **backgroundColor** | Sets the background color of the media recorder. | `mediaRecorderStyle.backgroundColor: UIColor = CometChatTheme.backgroundColor01` |
+| **borderWidth** | Defines the width of the border for the media recorder. | `mediaRecorderStyle.borderWidth: CGFloat = 1` |
+| **borderColor** | Specifies the border color of the media recorder. | `mediaRecorderStyle.borderColor: UIColor = CometChatTheme.borderColorLight` |
+| **cornerRadius** | Configures the corner radius of the media recorder. | `mediaRecorderStyle.cornerRadius: CometChatCornerStyle? = nil` |
+| **recordingButtonBackgroundColor** | Sets the background color of the recording button. | `mediaRecorderStyle.recordingButtonBackgroundColor: UIColor = CometChatTheme.iconColorHighlight` |
+| **recordingButtonCornerRadius** | Configures the corner radius of the recording button. | `mediaRecorderStyle.recordingButtonCornerRadius: CometChatCornerStyle? = nil` |
+| **recordingButtonBorderWidth** | Sets the border width of the recording button. | `mediaRecorderStyle.recordingButtonBorderWidth: CGFloat = 0` |
+| **recordingButtonBorderColor** | Sets the border color of the recording button. | `mediaRecorderStyle.recordingButtonBorderColor: UIColor = .clear` |
+| **recordingButtonImageTintColor** | Specifies the tint color of the recording button image. | `mediaRecorderStyle.recordingButtonImageTintColor: UIColor = CometChatTheme.white` |
+| **recordingButtonImage** | The image displayed on the recording button. | `mediaRecorderStyle.recordingButtonImage: UIImage = UIImage(systemName: "mic.fill") ?? UIImage()` |
+| **deleteButtonBackgroundColor** | Sets the background color of the delete button. | `mediaRecorderStyle.deleteButtonBackgroundColor: UIColor = CometChatTheme.backgroundColor01` |
+| **deleteButtonImageTintColor** | Specifies the tint color of the delete button image. | `mediaRecorderStyle.deleteButtonImageTintColor: UIColor = CometChatTheme.iconColorSecondary` |
+| **deleteButtonImage** | The image displayed on the delete button. | `mediaRecorderStyle.deleteButtonImage: UIImage = UIImage(systemName: "trash.fill") ?? UIImage()` |
+| **deleteButtonCornerRadius** | Configures the corner radius of the delete button. | `mediaRecorderStyle.deleteButtonCornerRadius: CometChatCornerStyle? = nil` |
+| **deleteButtonBorderWidth** | Sets the border width of the delete button. | `mediaRecorderStyle.deleteButtonBorderWidth: CGFloat = 1` |
+| **deleteButtonBorderColor** | Specifies 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](/ui-kit/ios/component-styling#media-recorder) styles.
+
+**Global level styling**
+
+
+
+```swift
+CometChatMessageComposer.aiOptionsStyle.backgroundColor = UIColor(hex: "#FFF9F5")
+CometChatMessageComposer.aiOptionsStyle.textColor = .black
+CometChatMessageComposer.aiOptionsStyle.aiImageTintColor = UIColor(hex: "#F76808")
```
+
+
-### footerView
+**Instance level styling**
-Custom view below the composer input.
+
+
+```swift
+var aIOptionsStyle = AIOptionsStyle()
+aIOptionsStyle.backgroundColor = UIColor(hex: "#FFF9F5")
+aIOptionsStyle.textColor = .black
+aIOptionsStyle.aiImageTintColor = UIColor(hex: "#F76808")
-```swift lines
-import UIKit
-import CometChatUIKitSwift
+let messageComposer = CometChatMessageComposer()
+messageComposer.aiOptionsStyle = aIOptionsStyle
+```
+
+
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-
-composer.set(footerView: { user, group in
- let view = UIView()
-
- let label = UILabel()
- label.text = "Messages are end-to-end encrypted"
- label.font = UIFont.systemFont(ofSize: 12)
- label.textColor = .secondaryLabel
- view.addSubview(label)
-
- return view
+
+
+
+
+The following properties are exposed by AI Options Style:
+
+| **Property** | **Description** | **Code** |
+| ---------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------ |
+| **errorViewTextFont** | Specifies the font used for the text in the error view. | `aIOptionsStyle.errorViewTextFont: UIFont?` |
+| **errorViewTextColor** | Sets the color of the text in the error view. | `aIOptionsStyle.errorViewTextColor: UIColor?` |
+| **emptyViewTextFont** | Specifies the font used for the text in the empty view. | `aIOptionsStyle.emptyViewTextFont: UIFont?` |
+| **emptyViewTextColor** | Sets the color of the text in the empty view. | `aIOptionsStyle.emptyViewTextColor: UIColor?` |
+| **aiImageTintColor** | Configures the tint color for AI-related images. | `aIOptionsStyle.aiImageTintColor: UIColor = CometChatTheme.iconColorHighlight` |
+| **textColor** | Sets the color of the text. | `aIOptionsStyle.textColor: UIColor = CometChatTheme.textColorPrimary` |
+| **textFont** | Specifies the font for the text. | `aIOptionsStyle.textFont: UIFont = CometChatTypography.Heading4.regular` |
+| **backgroundColor** | Sets the background color. | `aIOptionsStyle.backgroundColor: UIColor = CometChatTheme.backgroundColor01` |
+| **borderWidth** | Sets the width of the border. | `aIOptionsStyle.borderWidth: CGFloat = 0` |
+| **borderColor** | Sets the color of the border. | `aIOptionsStyle.borderColor: UIColor = .clear` |
+| **cornerRadius** | Configures 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
+
+| Property | Description | Code |
+| --------------------------------- | -------------------------------------------------------- | ------------------------------------------ |
+| setInitialComposerText | Sets the initial text in the composer when it loads. | `setInitialComposerText("Hello")` |
+| disableTypingEvents | Disables sending typing indicators when the user types. | `disableTypingEvents = true` |
+| disableMentions | Disables the mention feature in the composer. | `disableMentions = true` |
+| hideImageAttachmentOption | Hides the option to attach images. | `hideImageAttachmentOption = true` |
+| hideVideoAttachmentOption | Hides the option to attach videos. | `hideVideoAttachmentOption = true` |
+| hideAudioAttachmentOption | Hides the option to attach audio files. | `hideAudioAttachmentOption = true` |
+| hideFileAttachmentOption | Hides the option to attach files. | `hideFileAttachmentOption = true` |
+| hidePollsOption | Hides the option to create polls. | `hidePollsOption = true` |
+| hideCollaborativeDocumentOption | Hides the option for collaborative documents. | `hideCollaborativeDocumentOption = true` |
+| hideCollaborativeWhiteboardOption | Hides the option for collaborative whiteboards. | `hideCollaborativeWhiteboardOption = true` |
+| hideAttachmentButton | Hides the attachment button in the composer. | `hideAttachmentButton = true` |
+| hideVoiceRecordingButton | Hides the voice recording button. | `hideVoiceRecordingButton = true` |
+| hideStickersButton | Hides the stickers button. | `hideStickersButton = true` |
+| hideSendButton | Hides the send button. | `hideSendButton = true` |
+| setUser | Sets the user for direct messaging. | `set(user: User)` |
+| setGroup | Sets the group for group messaging. | `set(group: Group)` |
+| setParentMessageId | Sets the parent message ID for replying in a thread. | `set(parentMessageId: 12345)` |
+| setMaxLine | Sets the maximum number of lines for the composer input. | `set(maxLine: 3)` |
+| setCustomSoundForMessages | Sets a custom sound for sending messages. | `set(customSoundForMessages: URL?)` |
+| disableSoundForMessages | Disables 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`.
+
+
+
+```swift
+let messageComposer = CometChatMessageComposer()
+messageComposer.set(attachmentOptions: { user, group, controller in
+return [CometChatMessageComposerAction]
})
```
+
+
-### sendButtonView
+**Demonstration**
-Replace the send button.
+
+
+
-```swift lines
-import UIKit
-import CometChatUIKitSwift
+In this example, we are overriding the existing MessageComposerActions List with Capture Photo actions.
+
+
+
+```swift
+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
-let composer = CometChatMessageComposer()
-composer.set(user: user)
+By using `set(sendButtonView:)`, you can set a custom send button for the MessageComposer Component.
-composer.set(sendButtonView: { user, group in
- let button = UIButton(type: .system)
- button.setImage(UIImage(systemName: "paperplane.fill"), for: .normal)
- button.tintColor = .systemBlue
- return button
+
+
+```swift
+let messageComposer = CustomSendButton()
+messageComposer.set(sendButtonView: { user, group in
+let view = CustomSendButton()
+return view
})
```
+
+
-### auxillaryButtonView
+**Demonstration**
-Replace the sticker and AI button area.
+
+
+
-```swift lines
+
+
+```swift
import UIKit
-import CometChatUIKitSwift
-
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-
-composer.set(auxillaryButtonView: { user, group in
- let stackView = UIStackView()
- stackView.axis = .horizontal
- stackView.spacing = 8
-
- let aiButton = UIButton(type: .system)
- aiButton.setImage(UIImage(systemName: "sparkles"), for: .normal)
-
- let emojiButton = UIButton(type: .system)
- emojiButton.setImage(UIImage(systemName: "face.smiling"), for: .normal)
-
- stackView.addArrangedSubview(aiButton)
- stackView.addArrangedSubview(emojiButton)
-
- return stackView
-})
+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)?
+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?()
+}
+}
```
+
+
-### attachmentOptions
+***
-Override the default attachment options.
+#### HeaderView
-```swift lines
-import UIKit
-import CometChatUIKitSwift
+By using `set(headerView:)`, you can set a custom header view for the MessageComposer Component.
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-
-composer.set(attachmentOptions: { user, group, controller in
- return [
- CometChatMessageComposerAction(
- id: "photo",
- text: "Photo",
- startIcon: UIImage(systemName: "photo"),
- startIconTint: .systemBlue,
- onActionClick: { print("Photo selected") }
- ),
- CometChatMessageComposerAction(
- id: "camera",
- text: "Camera",
- startIcon: UIImage(systemName: "camera"),
- startIconTint: .systemGreen,
- onActionClick: { print("Camera selected") }
- ),
- CometChatMessageComposerAction(
- id: "location",
- text: "Location",
- startIcon: UIImage(systemName: "location"),
- startIconTint: .systemRed,
- onActionClick: { print("Location selected") }
- )
- ]
+
+
+```swift
+let messageComposer = CometChatMessageComposer()
+messageComposer.set(headerView: { user, group in
+let view = CustomHeaderView()
+return view
})
```
+
+
----
-
-## Common Patterns
+**Demonstration**
-### Thread composer
+
+
+
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-composer.set(parentMessageId: parentMessage.id)
+
+
+```swift
+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)
+])
+}
+}
```
+
+
-### Minimal composer — text only
+***
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-composer.hideAttachmentButton = true
-composer.hideVoiceRecordingButton = true
-composer.hideStickersButton = true
-composer.hideAIButton = true
-```
+#### SetTextFormatters
-### Pre-filled text
+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](/ui-kit/ios/mentions-formatter-guide)
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-composer.setInitialComposerText("Hello! ")
-composer.placeholderText = "Type a message..."
-```
+**Example**
-### Disable typing indicators
+
+
+```swift
+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))
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-composer.disableTypingEvents = true
-```
+let customMentionFormatter = CometChatMentionsFormatter()
+.set(composerTextStyle: composerTextStyle)
-### Disable mentions
+let messageComposerConfiguration = MessageComposerConfiguration()
+.set(textFormatter: [customMentionFormatter])
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
-composer.disableMentions = true
+let cometChatMessages = CometChatMessages()
+.set(user: user)
+.set(messageComposerConfiguration: messageComposerConfiguration)
```
+
+
-### Custom send button action
+***
-```swift lines
-let composer = CometChatMessageComposer()
-composer.set(user: user)
+
+To ensure that the `MessageComposer` is properly configured, passing the controller is mandatory.
-composer.set(onSendButtonClick: { message in
- print("Sending message: \(message)")
-})
+```swift
+let composerView = CometChatMessageComposer()
+composerView.set(controller: UIViewController) // Passing the controller is required
```
+
----
+***
-## Styling
+
+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.
+
-### Style Hierarchy
+---
-1. Global styles (`CometChatMessageComposer.style`) apply to all instances
-2. Instance styles override global for specific instances
+## Compact Message Composer
-### Global Level Styling
+`CometChatCompactMessageComposer` is a compact message composer component with built-in rich text formatting support. It provides a streamlined, single-line input experience with an expandable text area and a formatting toolbar.
-```swift lines
-import CometChatUIKitSwift
+
+
+
+
+### Usage
-CometChatMessageComposer.style.backgroundColor = .systemBackground
-CometChatMessageComposer.style.activeSendButtonImageBackgroundColor = .systemBlue
-CometChatMessageComposer.style.attachmentImageTint = .systemGray
-CometChatMessageComposer.style.voiceRecordingImageTint = .systemGray
+
+
+```swift
+let compactComposer = CometChatCompactMessageComposer()
+compactComposer.set(user: user)
+compactComposer.set(controller: self)
+```
+
+
+
+#### Enabling Rich Text Formatting
+
+
+
+```swift
+let compactComposer = CometChatCompactMessageComposer()
+compactComposer.showRichTextFormattingOptions = true // Shows the formatting toolbar
+compactComposer.enableRichTextFormatting = true // Enables markdown conversion
+compactComposer.set(user: user)
+compactComposer.set(controller: self)
```
+
+
-### Instance Level Styling
+#### Complete Integration Example
-```swift lines
+
+
+```swift
+import UIKit
import CometChatUIKitSwift
-var customStyle = MessageComposerStyle()
-customStyle.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
-customStyle.activeSendButtonImageBackgroundColor = .systemOrange
-customStyle.composeBoxBackgroundColor = .white
-customStyle.composeBoxBorderColor = .systemGray4
+class ChatViewController: UIViewController {
-let composer = CometChatMessageComposer()
-composer.style = customStyle
-```
+var user: User?
-
-
-
+override func viewDidLoad() {
+super.viewDidLoad()
+setupComposer()
+}
-### Key Style Properties
-
-| Property | Type | Description |
-|----------|------|-------------|
-| `backgroundColor` | `UIColor` | Background color |
-| `borderWidth` | `CGFloat` | Border width |
-| `borderColor` | `UIColor` | Border color |
-| `cornerRadius` | `CometChatCornerStyle?` | Corner radius |
-| `placeHolderTextFont` | `UIFont` | Placeholder font |
-| `placeHolderTextColor` | `UIColor` | Placeholder color |
-| `textFiledColor` | `UIColor` | Input text color |
-| `textFiledFont` | `UIFont` | Input text font |
-| `sendButtonImage` | `UIImage?` | Send button icon |
-| `sendButtonImageTint` | `UIColor` | Send button tint |
-| `activeSendButtonImageBackgroundColor` | `UIColor` | Active send button background |
-| `inactiveSendButtonImageBackgroundColor` | `UIColor` | Inactive send button background |
-| `composeBoxBackgroundColor` | `UIColor` | Compose box background |
-| `composeBoxBorderColor` | `UIColor` | Compose box border color |
-| `composeBoxBorderWidth` | `CGFloat` | Compose box border width |
-| `attachmentImage` | `UIImage?` | Attachment button icon |
-| `attachmentImageTint` | `UIColor` | Attachment icon tint |
-| `voiceRecordingImage` | `UIImage?` | Voice recording icon |
-| `voiceRecordingImageTint` | `UIColor` | Voice recording tint |
-
-### Sub-Component Styles
-
-| Property | Type | Description |
-|----------|------|-------------|
-| `mediaRecorderStyle` | `MediaRecorderStyle` | Voice recording interface |
-| `attachmentSheetStyle` | `AttachmentSheetStyle` | Attachment options sheet |
-| `suggestionsStyle` | `SuggestionsStyle` | Mentions suggestions view |
-| `aiOptionsStyle` | `AIOptionsStyle` | AI options menu |
-| `mentionStyle` | `MentionStyle` | Mentions appearance |
-
-### Customization Matrix
-
-| What to change | Where | Property/API |
-|----------------|-------|--------------|
-| Override send behavior | Callback | `set(onSendButtonClick:)` |
-| Track text input | Callback | `set(onTextChangedListener:)` |
-| Toggle visibility | Props | `hide` boolean props |
-| Custom attachments | View Slot | `set(attachmentOptions:)` |
-| Replace UI sections | View Slot | `set(headerView:)`, `set(sendButtonView:)` |
-| Change colors, fonts | Style | `MessageComposerStyle` properties |
+private func setupComposer() {
+guard let user = user else { return }
----
+// Create and configure the composer
+let compactComposer = CometChatCompactMessageComposer()
+compactComposer.set(user: user)
+compactComposer.set(controller: self)
-## Props
-
-All props are optional. Sorted alphabetically.
-
-| Property | Type | Default | Description |
-|----------|------|---------|-------------|
-| `disableMentions` | `Bool` | `false` | Disables the @mention feature |
-| `disableSoundForMessages` | `Bool` | `false` | Disables sound when sending messages |
-| `disableTypingEvents` | `Bool` | `false` | Disables sending typing indicators |
-| `hideAIButton` | `Bool` | `false` | Hides the AI button |
-| `hideAttachmentButton` | `Bool` | `false` | Hides the attachment button |
-| `hideAudioAttachmentOption` | `Bool` | `false` | Hides the audio attachment option |
-| `hideCollaborativeDocumentOption` | `Bool` | `false` | Hides the collaborative document option |
-| `hideCollaborativeWhiteboardOption` | `Bool` | `false` | Hides the collaborative whiteboard option |
-| `hideFileAttachmentOption` | `Bool` | `false` | Hides the file attachment option |
-| `hideFooterView` | `Bool` | `false` | Hides the footer view |
-| `hideHeaderView` | `Bool` | `false` | Hides the header view |
-| `hideImageAttachmentOption` | `Bool` | `false` | Hides the image attachment option |
-| `hidePollsOption` | `Bool` | `false` | Hides the polls option |
-| `hideSendButton` | `Bool` | `false` | Hides the send button |
-| `hideStickersButton` | `Bool` | `false` | Hides the stickers button |
-| `hideVideoAttachmentOption` | `Bool` | `false` | Hides the video attachment option |
-| `hideVoiceRecordingButton` | `Bool` | `false` | Hides the voice recording button |
-| `maxLine` | `Int` | `5` | Maximum lines before scrolling |
-| `placeholderText` | `String` | `"Type a message..."` | Placeholder text |
-| `textFormatters` | `[CometChatTextFormatter]` | `[]` | Custom text formatters |
+// Enable rich text formatting
+compactComposer.showRichTextFormattingOptions = true
+compactComposer.enableRichTextFormatting = true
----
+// Customize appearance
+compactComposer.set(placeholder: "Type a message...")
-## Methods
+// Add to view hierarchy
+compactComposer.translatesAutoresizingMaskIntoConstraints = false
+view.addSubview(compactComposer)
-### set(textFormatter:)
+NSLayoutConstraint.activate([
+compactComposer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+compactComposer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+compactComposer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
+])
+}
+}
+```
+
+
+
+---
-Sets a custom text formatter for the composer input.
+### CompactMessageComposerStyle
-```swift lines
-let composer = CometChatMessageComposer()
-let mentionFormatter = MentionTextFormatter(trackingCharacter: "@")
-composer.set(textFormatter: mentionFormatter)
+**Global level styling**
+
+
+
+```swift
+CometChatCompactMessageComposer.style.activeSendButtonBackgroundColor = UIColor(hex: "#F76808")
+CometChatCompactMessageComposer.style.attachmentImageTint = UIColor(hex: "#F76808")
+CometChatCompactMessageComposer.style.voiceRecordingImageTint = UIColor(hex: "#F76808")
```
+
+
-### setDisableMentionAll(_:)
+**Instance level styling**
-Disables or enables the @all mention feature that notifies all group members.
+
+
+```swift
+var customStyle = CompactMessageComposerStyle()
+customStyle.activeSendButtonBackgroundColor = UIColor(hex: "#F76808")
+customStyle.attachmentImageTint = UIColor(hex: "#F76808")
-```swift lines
-let composer = CometChatMessageComposer()
-composer.setDisableMentionAll(true)
+let compactComposer = CometChatCompactMessageComposer()
+compactComposer.style = customStyle
```
+
+
-### setMentionAllLabel(_:_:)
+**Complete Styling Example**
-Customizes the label displayed for @all mentions in the suggestions list.
+
+
+```swift
+// Create custom style
+var customStyle = CompactMessageComposerStyle()
+customStyle.backgroundColor = UIColor(hex: "#F5F5F5")
+customStyle.composeBoxBackgroundColor = .white
+customStyle.composeBoxBorderColor = UIColor(hex: "#E0E0E0")
+customStyle.textFieldColor = .black
+customStyle.placeholderColor = UIColor(hex: "#999999")
+customStyle.activeSendButtonBackgroundColor = UIColor(hex: "#6851D6")
+customStyle.inactiveSendButtonBackgroundColor = UIColor(hex: "#CCCCCC")
+customStyle.attachmentImageTint = UIColor(hex: "#6851D6")
+customStyle.voiceRecordingImageTint = UIColor(hex: "#6851D6")
+
+// Create custom toolbar style for rich text formatting
+var toolbarStyle = RichTextToolbarStyle()
+toolbarStyle.backgroundColor = UIColor(hex: "#FAFAFA")
+toolbarStyle.iconTintColor = UIColor(hex: "#666666")
+toolbarStyle.activeIconTintColor = UIColor(hex: "#6851D6")
+toolbarStyle.activeButtonBackgroundColor = UIColor(hex: "#EDE9FC")
+customStyle.richTextToolbarStyle = toolbarStyle
+
+// Apply to composer
+let compactComposer = CometChatCompactMessageComposer()
+compactComposer.style = customStyle
+compactComposer.showRichTextFormattingOptions = true
+compactComposer.enableRichTextFormatting = true
+compactComposer.set(user: user)
+compactComposer.set(controller: self)
+```
+
+
+
+The following properties are exposed by CompactMessageComposerStyle:
+
+| Property | Description | Code |
+| -------- | ----------- | ---- |
+| backgroundColor | Background color of the composer container. | `style.backgroundColor = CometChatTheme.backgroundColor03` |
+| composeBoxBackgroundColor | Background color for the compose box. | `style.composeBoxBackgroundColor = CometChatTheme.backgroundColor01` |
+| composeBoxBorderColor | Border color for the compose box. | `style.composeBoxBorderColor = CometChatTheme.borderColorDefault` |
+| textFieldFont | Font for the input text field. | `style.textFieldFont = CometChatTypography.Body.regular` |
+| textFieldColor | Text color for the input field. | `style.textFieldColor = CometChatTheme.textColorPrimary` |
+| placeholderColor | Color for the placeholder text. | `style.placeholderColor = CometChatTheme.textColorTertiary` |
+| sendButtonImage | Icon for the send button. | `style.sendButtonImage = UIImage(named: "custom-send")` |
+| sendButtonImageTint | Tint color for the send button image. | `style.sendButtonImageTint = CometChatTheme.white` |
+| activeSendButtonBackgroundColor | Background color for send button when active. | `style.activeSendButtonBackgroundColor = CometChatTheme.primaryColor` |
+| inactiveSendButtonBackgroundColor | Background color for send button when inactive. | `style.inactiveSendButtonBackgroundColor = CometChatTheme.neutralColor300` |
+| attachmentImage | Icon for the attachment button. | `style.attachmentImage = UIImage(systemName: "plus.circle")` |
+| attachmentImageTint | Tint color for the attachment image. | `style.attachmentImageTint = CometChatTheme.iconColorSecondary` |
+| voiceRecordingImage | Icon for the voice recording button. | `style.voiceRecordingImage = UIImage(systemName: "mic")` |
+| voiceRecordingImageTint | Tint color for the voice recording image. | `style.voiceRecordingImageTint = CometChatTheme.iconColorSecondary` |
+| stickersImage | Icon for the stickers button. | `style.stickersImage = UIImage(named: "sticker-image")` |
+| stickersImageTint | Tint color for the stickers image. | `style.stickersImageTint = CometChatTheme.iconColorSecondary` |
+| richTextToolbarStyle | Style configuration for the rich text toolbar. | `style.richTextToolbarStyle = RichTextToolbarStyle()` |
-```swift lines
-let composer = CometChatMessageComposer()
-composer.setMentionAllLabel("Everyone", "Notify all members in this group")
+---
+
+### Functionality
+
+These properties allow you to customize the behavior of the CometChatCompactMessageComposer.
+
+| Property | Description | Code |
+| -------- | ----------- | ---- |
+| set(user:) | Sets the user for direct messaging. | `set(user: User)` |
+| set(group:) | Sets the group for group messaging. | `set(group: Group)` |
+| set(parentMessageId:) | Sets the parent message ID for thread replies. | `set(parentMessageId: 12345)` |
+| set(placeholder:) | Sets the placeholder text. | `set(placeholder: "Type a message...")` |
+| disable(soundForMessages:) | Disables sound while sending messages. | `disable(soundForMessages: true)` |
+| disable(typingEvents:) | Disables sending typing indicators. | `disable(typingEvents: true)` |
+| disable(mentions:) | Disables the mention feature. | `disable(mentions: true)` |
+| hideAttachmentButton | Hides the attachment button. | `hideAttachmentButton = true` |
+| hideVoiceRecordingButton | Hides the voice recording button. | `hideVoiceRecordingButton = true` |
+| hideStickersButton | Hides the stickers button. | `hideStickersButton = true` |
+| hideSendButton | Hides the send button. | `hideSendButton = true` |
+| showRichTextFormattingOptions | Shows/hides the rich text formatting toolbar. | `showRichTextFormattingOptions = true` |
+| enableRichTextFormatting | Enables rich text formatting and markdown conversion. | `enableRichTextFormatting = true` |
+
+**Example**
+
+
+
+```swift
+let compactComposer = CometChatCompactMessageComposer()
+
+// Set user or group
+compactComposer.set(user: user)
+// OR for group messaging
+// compactComposer.set(group: group)
+
+// For thread replies
+compactComposer.set(parentMessageId: 12345)
+
+// Customize placeholder
+compactComposer.set(placeholder: "Type your message...")
+
+// Disable features
+compactComposer.disable(soundForMessages: true)
+compactComposer.disable(typingEvents: true)
+compactComposer.disable(mentions: true)
+
+// Hide UI elements
+compactComposer.hideAttachmentButton = true
+compactComposer.hideVoiceRecordingButton = true
+compactComposer.hideStickersButton = true
+
+// Enable rich text formatting
+compactComposer.showRichTextFormattingOptions = true
+compactComposer.enableRichTextFormatting = true
+
+// Required: Set the controller
+compactComposer.set(controller: self)
```
+
+
---
-## Related Components
+## Rich Text Formatting
+
+The Rich Text Formatting feature allows users to format messages with various text styles. When enabled, a formatting toolbar appears below the text input.
+
+### Supported Format Types
-- [Message List](/ui-kit/ios/message-list) — Display messages in a conversation
-- [Message Header](/ui-kit/ios/message-header) — Display user/group details
-- [Mentions Formatter](/ui-kit/ios/mentions-formatter-guide) — Configure @mention formatting
+| Format | Description | Markdown Syntax |
+| ------ | ----------- | --------------- |
+| Bold | Makes text bold | `**text**` |
+| Italic | Makes text italic | `*text*` |
+| Underline | Underlines text | `text` |
+| Strikethrough | Strikes through text | `~~text~~` |
+| Link | Creates a hyperlink | `[text](url)` |
+| Numbered List | Creates a numbered list | `1. item` |
+| Bullet List | Creates a bullet list | `- item` |
+| Blockquote | Creates a blockquote | `> text` |
+| Inline Code | Formats as inline code | `` `code` `` |
+| Code Block | Creates a code block | ` ```code``` ` |
+
+---
+
+### RichTextToolbarStyle
+
+**Global level styling**
+
+
+
+```swift
+CometChatCompactMessageComposer.style.richTextToolbarStyle.backgroundColor = UIColor(hex: "#F5F5F5")
+CometChatCompactMessageComposer.style.richTextToolbarStyle.iconTintColor = UIColor(hex: "#666666")
+CometChatCompactMessageComposer.style.richTextToolbarStyle.activeIconTintColor = UIColor(hex: "#F76808")
+CometChatCompactMessageComposer.style.richTextToolbarStyle.activeButtonBackgroundColor = UIColor(hex: "#FFF0E6")
+```
+
+
+
+The following properties are exposed by RichTextToolbarStyle:
+
+| Property | Description | Code |
+| -------- | ----------- | ---- |
+| backgroundColor | Background color of the toolbar. | `toolbarStyle.backgroundColor = CometChatTheme.backgroundColor02` |
+| borderColor | Border color of the toolbar. | `toolbarStyle.borderColor = CometChatTheme.borderColorLight` |
+| buttonSize | Size of format buttons. | `toolbarStyle.buttonSize = 30` |
+| buttonSpacing | Spacing between format buttons. | `toolbarStyle.buttonSpacing = CometChatSpacing.Spacing.s2` |
+| iconTintColor | Tint color for inactive format icons. | `toolbarStyle.iconTintColor = CometChatTheme.iconColorSecondary` |
+| activeIconTintColor | Tint color for active format icons. | `toolbarStyle.activeIconTintColor = CometChatTheme.primaryColor` |
+| buttonBackgroundColor | Background color for inactive buttons. | `toolbarStyle.buttonBackgroundColor = .clear` |
+| activeButtonBackgroundColor | Background color for active buttons. | `toolbarStyle.activeButtonBackgroundColor = CometChatTheme.extendedPrimaryColor100` |