Skip to main content
The CometChatGroupMembers component displays all members of a group with their roles (owner, admin, moderator, participant). It supports member management actions like kick, ban, and role changes based on the logged-in user’s permissions.
{
  "component": "CometChatGroupMembers",
  "package": "CometChatUIKitSwift",
  "import": "import CometChatUIKitSwift\nimport CometChatSDK",
  "description": "Displays all members of a group with their roles and supports member management actions like kick, ban, and role changes.",
  "inherits": "UIViewController",
  "primaryOutput": {
    "callback": "onItemClick",
    "type": "(GroupMember, IndexPath) -> Void"
  },
  "props": {
    "data": {
      "group": {
        "type": "Group",
        "required": true,
        "note": "The group whose members to display"
      },
      "groupMembersRequestBuilder": {
        "type": "GroupMembersRequest.GroupMembersRequestBuilder?",
        "default": "nil",
        "note": "Custom request builder for filtering members"
      }
    },
    "callbacks": {
      "onItemClick": "(GroupMember, IndexPath) -> Void",
      "onItemLongClick": "(GroupMember, IndexPath) -> Void",
      "onBack": "() -> Void",
      "onSelection": "([GroupMember]) -> Void",
      "onError": "(CometChatException) -> Void",
      "onEmpty": "() -> Void",
      "onLoad": "([GroupMember]) -> Void"
    },
    "visibility": {
      "hideSearch": { "type": "Bool", "default": false },
      "hideNavigationBar": { "type": "Bool", "default": false },
      "hideBackIcon": { "type": "Bool", "default": false },
      "hideUserStatus": { "type": "Bool", "default": false },
      "hideKickMemberOption": { "type": "Bool", "default": false },
      "hideBanMemberOption": { "type": "Bool", "default": false },
      "hideScopeChangeOption": { "type": "Bool", "default": false },
      "hideErrorView": { "type": "Bool", "default": false },
      "hideLoadingState": { "type": "Bool", "default": false }
    },
    "selection": {
      "selectionMode": { "type": "SelectionMode", "default": ".none" }
    },
    "viewSlots": {
      "listItemView": "(GroupMember?) -> UIView",
      "leadingView": "(GroupMember?) -> UIView",
      "titleView": "(GroupMember?) -> UIView",
      "subtitleView": "(GroupMember?) -> UIView",
      "trailView": "(GroupMember?) -> UIView",
      "emptyStateView": "UIView",
      "errorStateView": "UIView",
      "loadingStateView": "UIView"
    }
  },
  "events": [
    {
      "name": "ccGroupMemberKicked",
      "payload": "{ user: User, group: Group }",
      "description": "Fires when a member is kicked"
    },
    {
      "name": "ccGroupMemberBanned",
      "payload": "{ user: User, group: Group }",
      "description": "Fires when a member is banned"
    },
    {
      "name": "ccGroupMemberScopeChanged",
      "payload": "{ user: User, group: Group, scope: MemberScope }",
      "description": "Fires when a member's scope is changed"
    }
  ],
  "sdkListeners": [
    "onGroupMemberKicked",
    "onGroupMemberBanned",
    "onGroupMemberUnbanned",
    "onGroupMemberScopeChanged",
    "onMemberAddedToGroup"
  ],
  "compositionExample": {
    "description": "GroupMembers is typically accessed from group details or settings",
    "components": ["CometChatGroups", "CometChatGroupMembers", "CometChatMessages"],
    "flow": "User opens group → views members → taps member → starts direct chat"
  },
  "types": {
    "GroupMember": {
      "uid": "String",
      "name": "String",
      "avatar": "String?",
      "scope": "MemberScope",
      "joinedAt": "Int"
    },
    "MemberScope": {
      "owner": "Group owner with full permissions",
      "admin": "Administrator with management permissions",
      "moderator": "Moderator with limited management",
      "participant": "Regular member"
    }
  }
}

Where It Fits

CometChatGroupMembers displays all members of a specific group. It’s typically accessed from group details or settings screens.
import UIKit
import CometChatUIKitSwift
import CometChatSDK

class GroupDetailViewController: UIViewController {
    
    var group: Group!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupGroupMembers()
    }
    
    private func setupGroupMembers() {
        let groupMembers = CometChatGroupMembers(group: group)
        
        // Handle member tap - start direct chat
        groupMembers.set(onItemClick: { [weak self] member, indexPath in
            self?.startDirectChat(with: member)
        })
        
        let navController = UINavigationController(rootViewController: groupMembers)
        present(navController, animated: true)
    }
    
    private func startDirectChat(with member: GroupMember) {
        let messagesVC = CometChatMessages()
        messagesVC.set(user: member)
        navigationController?.pushViewController(messagesVC, animated: true)
    }
}

Minimal Render

import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)
let navController = UINavigationController(rootViewController: groupMembers)
present(navController, animated: true)

Filtering

Use GroupMembersRequest.GroupMembersRequestBuilder to filter which members appear in the list.
import CometChatUIKitSwift
import CometChatSDK

// Create a custom request builder
let requestBuilder = GroupMembersRequest.GroupMembersRequestBuilder(guid: group.guid)
    .set(limit: 30)
    .set(scopes: ["admin", "moderator"])

let groupMembers = CometChatGroupMembers(
    group: group,
    groupMembersRequestBuilder: requestBuilder
)

Filter Recipes

RecipeCode
Admins only.set(scopes: ["admin"])
Admins and moderators.set(scopes: ["admin", "moderator"])
Search by name.set(searchKeyword: "john")
Limit results.set(limit: 20)

Actions and Events

Callback Props

onItemClick

Fires when a user taps on a member. Use this to start a direct chat or view profile.
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(onItemClick: { [weak self] member, indexPath in
    guard let self = self else { return }
    
    let messagesVC = CometChatMessages()
    messagesVC.set(user: member)
    self.navigationController?.pushViewController(messagesVC, animated: true)
})

onItemLongClick

Fires when a user long-presses on a member. Use this to show member options.
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(onItemLongClick: { [weak self] member, indexPath in
    guard let self = self else { return }
    
    let alert = UIAlertController(title: member.name, message: nil, preferredStyle: .actionSheet)
    
    alert.addAction(UIAlertAction(title: "Message", style: .default) { _ in
        // Start direct chat
    })
    
    alert.addAction(UIAlertAction(title: "View Profile", style: .default) { _ in
        // View profile
    })
    
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
    self.present(alert, animated: true)
})

onBack

Fires when the back button is pressed.
import CometChatUIKitSwift

let groupMembers = CometChatGroupMembers(group: group)

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

onSelection

Fires when members are selected in selection mode.
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)
groupMembers.selectionMode = .multiple

groupMembers.set(onSelection: { [weak self] selectedMembers in
    print("Selected \(selectedMembers.count) members")
})

onError

Fires when an error occurs while loading members.
import CometChatUIKitSwift

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(onError: { error in
    print("Error loading members: \(error.errorDescription)")
})

onEmpty

Fires when the member list is empty.
import CometChatUIKitSwift

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(onEmpty: {
    print("No members found")
})

onLoad

Fires when members are successfully loaded.
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(onLoad: { members in
    print("Loaded \(members.count) members")
})

Actions Reference

MethodDescriptionExample
set(onItemClick:)Triggered when a member is tappedStart direct chat
set(onItemLongClick:)Triggered on long pressShow options menu
set(onBack:)Triggered when back button is pressedCustom navigation
set(onSelection:)Triggered in selection modeMulti-select members
set(onError:)Triggered when an error occursShow error alert
set(onEmpty:)Triggered when list is emptyShow empty state
set(onLoad:)Triggered when members loadAnalytics tracking

Global UI Events

EventFires whenPayload
ccGroupMemberKickedA member is kickedUser, Group
ccGroupMemberBannedA member is bannedUser, Group
ccGroupMemberScopeChangedA member’s role is changedUser, Group, MemberScope
import CometChatUIKitSwift
import CometChatSDK

class MyViewController: UIViewController, CometChatGroupEventListener {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        CometChatGroupEvents.addListener("my-listener", self)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        CometChatGroupEvents.removeListener("my-listener")
    }
    
    func onGroupMemberKick(kickedUser: User, kickedGroup: Group) {
        print("\(kickedUser.name ?? "") was kicked from \(kickedGroup.name ?? "")")
    }
    
    func onGroupMemberBan(bannedUser: User, bannedGroup: Group) {
        print("\(bannedUser.name ?? "") was banned from \(bannedGroup.name ?? "")")
    }
    
    func onGroupMemberChangeScope(updatedBy: User, updatedUser: User, scopeChangedTo: CometChat.MemberScope, scopeChangedFrom: CometChat.MemberScope, group: Group) {
        print("\(updatedUser.name ?? "") role changed to \(scopeChangedTo)")
    }
}

SDK Events (Real-Time, Automatic)

SDK ListenerInternal behavior
onGroupMemberKickedRemoves member from list
onGroupMemberBannedRemoves member from list
onGroupMemberUnbannedUpdates member info
onGroupMemberScopeChangedUpdates member role badge
onMemberAddedToGroupAdds new member to list

Custom View Slots

SlotSetter MethodSignatureReplaces
listItemViewset(listItemView:)(GroupMember?) -> UIViewEntire member row
leadingViewset(leadingView:)(GroupMember?) -> UIViewAvatar / left section
titleViewset(titleView:)(GroupMember?) -> UIViewName / title text
subtitleViewset(subtitleView:)(GroupMember?) -> UIViewRole / subtitle text
trailViewset(trailView:)(GroupMember?) -> UIViewRight side (role badge)
emptyStateView-UIViewEmpty state display
errorStateView-UIViewError state display
loadingStateView-UIViewLoading state display

subtitleView

Customize the subtitle area below the member name.
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(subtitleView: { member in
    let label = UILabel()
    label.font = UIFont.systemFont(ofSize: 12)
    label.textColor = UIColor.secondaryLabel
    
    guard let member = member else { return label }
    
    let date = Date(timeIntervalSince1970: Double(member.joinedAt))
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    label.text = "Joined: \(formatter.string(from: date))"
    
    return label
})

tailView

Customize the right side of the member row (role badge). Note: The setter method is set(trailView:).
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

groupMembers.set(trailView: { member in
    let badge = UILabel()
    badge.font = UIFont.systemFont(ofSize: 10, weight: .semibold)
    badge.textAlignment = .center
    badge.layer.cornerRadius = 10
    badge.clipsToBounds = true
    
    guard let member = member else { return badge }
    
    switch member.scope {
    case .owner:
        badge.text = "Owner"
        badge.textColor = UIColor.systemOrange
        badge.backgroundColor = UIColor.systemOrange.withAlphaComponent(0.2)
    case .admin:
        badge.text = "Admin"
        badge.textColor = UIColor.systemPurple
        badge.backgroundColor = UIColor.systemPurple.withAlphaComponent(0.2)
    case .moderator:
        badge.text = "Mod"
        badge.textColor = UIColor.systemBlue
        badge.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.2)
    default:
        badge.text = "Member"
        badge.textColor = UIColor.systemGray
        badge.backgroundColor = UIColor.systemGray.withAlphaComponent(0.2)
    }
    
    return badge
})

Styling

Style Hierarchy

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

Global Level Styling

import UIKit
import CometChatUIKitSwift

// Apply global styles
CometChatGroupMembers.style.backgroundColor = UIColor.systemBackground
CometChatGroupMembers.style.titleColor = UIColor.label
CometChatGroupMembers.style.titleFont = UIFont.systemFont(ofSize: 20, weight: .bold)
CometChatGroupMembers.style.listItemTitleTextColor = UIColor.label

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

Instance Level Styling

import UIKit
import CometChatUIKitSwift

var customStyle = GroupMembersStyle()
customStyle.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
customStyle.titleColor = UIColor.darkGray
customStyle.listItemBackground = UIColor.white

let groupMembers = CometChatGroupMembers(group: group)
groupMembers.style = customStyle

Key Style Properties

PropertyTypeDefaultDescription
backgroundColorUIColorCometChatTheme.backgroundColor01Background color
titleColorUIColorCometChatTheme.textColorPrimaryNavigation title color
titleFontUIFontCometChatTypography.Heading4.mediumNavigation title font
listItemTitleTextColorUIColorCometChatTheme.textColorPrimaryMember name color
listItemTitleFontUIFontCometChatTypography.Heading4.mediumMember name font
listItemSubTitleTextColorUIColorCometChatTheme.textColorSecondarySubtitle color
listItemBackgroundUIColor.clearList item background

Customization Matrix

What to changeWhereProperty/APIExample
Background colorStylebackgroundColorUIColor.systemBackground
Title appearanceStyletitleColor, titleFontCustom colors and fonts
List item lookStylelistItemBackgroundUIColor.white
Avatar appearanceStyleavatarStyleAvatarStyle() with custom radius
Hide searchPropertyhideSearchgroupMembers.hideSearch = true
Hide kick optionPropertyhideKickMemberOptiongroupMembers.hideKickMemberOption = true
Custom rowView Slotset(listItemView:)See Custom View Slots

Props

All props are optional except group. Sorted alphabetically.

group (required)

The group whose members to display.
TypeGroup
Requiredtrue

groupMembersRequestBuilder

Custom request builder for filtering members.
TypeGroupMembersRequest.GroupMembersRequestBuilder?
Defaultnil

hideBackIcon

Hides the back button in the navigation bar.
TypeBool
Defaultfalse

hideBanMemberOption

Hides the ban member option in swipe actions.
TypeBool
Defaultfalse

hideErrorView

Hides the error state view.
TypeBool
Defaultfalse

hideKickMemberOption

Hides the kick member option in swipe actions.
TypeBool
Defaultfalse

hideLoadingState

Hides the loading state indicator.
TypeBool
Defaultfalse

hideNavigationBar

Hides the entire navigation bar.
TypeBool
Defaultfalse

hideScopeChangeOption

Hides the role change option in swipe actions.
TypeBool
Defaultfalse

hideSearch

Hides the search bar.
TypeBool
Defaultfalse

hideUserStatus

Hides online/offline status indicators.
TypeBool
Defaultfalse

selectionMode

Sets the selection mode for multi-select functionality.
TypeSelectionMode
Default.none

Events

EventPayloadFires when
ccGroupMemberKickedUser, GroupA member is kicked
ccGroupMemberBannedUser, GroupA member is banned
ccGroupMemberScopeChangedUser, Group, MemberScopeA member’s role is changed

Custom Swipe Options

Add custom actions when swiping on a member:
import UIKit
import CometChatUIKitSwift
import CometChatSDK

let groupMembers = CometChatGroupMembers(group: group)

let deleteOption = CometChatGroupMemberOption(
    id: "delete",
    title: "Remove",
    icon: UIImage(systemName: "trash"),
    backgroundColor: .systemRed,
    onClick: { member, group, section, option, controller in
        print("Remove \(member.name ?? "")")
        // Implement remove logic
    }
)

let messageOption = CometChatGroupMemberOption(
    id: "message",
    title: "Message",
    icon: UIImage(systemName: "message"),
    backgroundColor: .systemBlue,
    onClick: { member, group, section, option, controller in
        let messages = CometChatMessages()
        messages.set(user: member)
        controller.navigationController?.pushViewController(messages, animated: true)
    }
)

groupMembers.setOptions(options: { group, member in
    return [messageOption, deleteOption]
})

Custom Menu Buttons

Add buttons to the navigation bar:
import UIKit
import CometChatUIKitSwift
import CometChatSDK

class GroupMembersViewController: UIViewController {
    
    var group: Group!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupGroupMembers()
    }
    
    private func setupGroupMembers() {
        let groupMembers = CometChatGroupMembers(group: group)
        
        let addButton = UIBarButtonItem(
            image: UIImage(systemName: "person.badge.plus"),
            style: .plain,
            target: self,
            action: #selector(addMemberTapped)
        )
        
        groupMembers.set(menus: [addButton])
        
        let navController = UINavigationController(rootViewController: groupMembers)
        present(navController, animated: true)
    }
    
    @objc func addMemberTapped() {
        // Show add member screen
        let addMembers = CometChatAddMembers(group: group)
        navigationController?.pushViewController(addMembers, animated: true)
    }
}

Troubleshooting

IssueSolution
Empty member listEnsure group object is valid and has members
Management options not showingCheck logged-in user’s permissions (must be admin/owner)
Search not workingVerify hideSearch is not set to true
Status not showingCheck that hideUserStatus is not set to true
Custom views not appearingEnsure custom view has proper constraints