Search for friends
The search friends page retrieves all friends from the current user's device. When the user enters keywords in the search field, Chat UI fetches friend information from the database.
Chat UI provides NCSearchFriendsViewController, a search page class based on UIKit's UITableView.
The search friends page typically consists of three parts: navigation bar, search bar, and friend list.

Initialize
Create a search friends page by initializing the NCSearchFriendsViewController class.
Note that you need to create a NCSearchFriendsViewModel object as the business logic handler for NCSearchFriendsViewController.
Parameters
| Parameter | Type | Description |
|---|---|---|
| viewModel | NCSearchFriendsViewModel | The business logic handler for NCSearchFriendsViewController. Handles UI configuration and friend information retrieval. |
Example
- Swift
- Objective-C
let viewModel = NCSearchFriendsViewModel()
let vc = NCSearchFriendsViewController(viewModel: viewModel)
self.navigationController?.pushViewController(vc, animated: true)
NCSearchFriendsViewModel *viewModel = [[NCSearchFriendsViewModel alloc] init];
NCSearchFriendsViewController *vc = [[NCSearchFriendsViewController alloc] initWithViewModel:viewModel];
[self.navigationController pushViewController:vc animated:YES];
Customization
You can customize the appearance of the Chat UI search friends interface.
Customize the title bar
NCSearchFriendsViewController uses the system navigation bar to display the page title. To customize the title, subclass NCSearchFriendsViewController and set the title property in viewDidLoad.
Example
- Swift
- Objective-C
override func viewDidLoad() {
super.viewDidLoad()
self.title = "New title"
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"New title";
}
Customize the search field
By default, NCSearchFriendsViewController searches for friends. To customize the search functionality, set the delegate property of NCSearchFriendsViewModel and implement the relevant delegate methods.
Example
- Swift
- Objective-C
let viewModel = NCSearchFriendsViewModel()
viewModel.delegate = self
let vc = NCSearchFriendsViewController(viewModel: viewModel)
self.navigationController?.pushViewController(vc, animated: true)
...
/// Configure custom search functionality
func willConfigureSearchBarViewModel(for viewModel: NCSearchFriendsViewModel) -> NCSearchBarViewModel? {
// Return custom search ViewModel
}
NCSearchFriendsViewModel *viewModel = [[NCSearchFriendsViewModel alloc] init];
viewModel.delegate = self;
NCSearchFriendsViewController *vc = [[NCSearchFriendsViewController alloc] initWithViewModel:viewModel];
[self.navigationController pushViewController:vc animated:YES];
...
/// Configure custom search functionality
- (NCSearchBarViewModel *_Nullable)willConfigureSearchBarViewModelForSearchFriendsViewModel:(NCSearchFriendsViewModel *_Nonnull)viewModel {
// Return custom search ViewModel
}
Customize the search friends page cell
1. Create a custom NCCustomCell
- Swift
- Objective-C
class NCCustomCell: UITableViewCell {
var titleLabel: UILabel!
var contentLabel: UILabel!
// Cell rendering
}
@interface NCCustomCell : UITableViewCell
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *contentLabel;
@end
@implementation
// Cell rendering
@end
2. Create a custom NCCustomCellViewModel
Custom CellViewModel must subclass NCFriendListCellViewModel.
- Swift
- Objective-C
typealias NCPermanentCellViewModelBlock = (UIViewController) -> Void
class NCCustomCellViewModel: NCFriendListCellViewModel {
var title: String
var portrait: UIImage
var touchBlock: NCPermanentCellViewModelBlock
/// Initialize
init(title: String, portrait: UIImage, touchBlock: @escaping NCPermanentCellViewModelBlock) {
self.title = title
self.portrait = portrait
self.touchBlock = touchBlock
super.init()
}
// Register and customize cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "NCCustomCellIdentifier"
// Register cell
tableView.register(NCCustomCell.self, forCellReuseIdentifier: cellIdentifier)
// Return cell
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? NCCustomCell else {
return UITableViewCell()
}
// Modify UI
cell.titleLabel.text = self.title
cell.contentLabel.text = self.detail
return cell
}
}
typedef void(^NCPermanentCellViewModelBlock)(UIViewController *);
@interface NCCustomCellViewModel : NCFriendListCellViewModel
/// Initialize
- (instancetype)initWithTitle:(NSString *)title
portrait:(UIImage *)portrait
touchBlock:(NCPermanentCellViewModelBlock)touchBlock;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) UIImage *portrait;
@property (nonatomic, copy) NCPermanentCellViewModelBlock touchBlock;
@end
@implementation NCCustomCellViewModel
- (instancetype)initWithTitle:(NSString *)title
portrait:(UIImage *)portrait
touchBlock:(NCPermanentCellViewModelBlock)touchBlock{
self = [super init];
if (self) {
self.title = title;
self.portrait = portrait;
self.touchBlock = touchBlock;
}
return self;
}
// Register and customize cell
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = @"NCCustomCellIdentifier";
// Register cell
[tableView registerClass:NCCustomCell.class forCellReuseIdentifier:cellIdentifier];
// Return cell
NCCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier
forIndexPath:indexPath];
// Modify UI
cell.titleLabel.text = self.title;
cell.contentLabel.text = self.detail;
return cell;
}
@end
3. Set NCSearchFriendsViewModel delegate
Set the delegate when initializing the NCSearchFriendsViewModel object:
- Swift
- Objective-C
let viewModel = NCSearchFriendsViewModel()
viewModel.delegate = self
NCSearchFriendsViewModel *viewModel = [[NCSearchFriendsViewModel alloc] init];
viewModel.delegate = self;
4. Modify the data source
Implement the delegate method:
- Swift
- Objective-C
// Friend data source
func searchFriendsViewModel(_ viewModel: NCSearchFriendsViewModel,
willLoadItemsIn dataSource: [Any]?) -> [Any]? {
// Process data source
var list = dataSource ?? []
let customCellVM = NCCustomCellViewModel(
title: "title",
portrait: UIImage(named: "newFriend")!
) { vc in
// Handle tap event
}
list.append(customCellVM)
return list
}
// Friend data source
- (NSArray *_Nullable)searchFriendsViewModel:(NCSearchFriendsViewModel *_Nonnull)viewModel
willLoadItemsInDataSource:(NSArray *_Nullable)dataSource {
// Process data source
NSMutableArray *list = dataSource.mutableCopy ?: [NSMutableArray array];
NCCustomCellViewModel *customCellVM = [[NCCustomCellViewModel alloc] initWithTitle:@"title" portrait:[UIImage imageNamed:@"newFriend"] touchBlock:^(UIViewController * vc) {
// Handle tap event
}];
[list addObject:customCellVM];
return list;
}
5. Customize cell tap handling
- Swift
- Objective-C
/// Handle cell tap events
/// - Parameters:
/// - viewModel: viewModel
/// - viewController: viewController
/// - tableView: tableView
/// - indexPath: indexPath
/// - cellViewModel: CellViewModel
/// - Returns: Whether the app handles the event [true: SDK won't process, false: SDK handles]
func searchFriendsViewModel(_ viewModel: NCSearchFriendsViewModel,
viewController: UIViewController,
tableView: UITableView,
didSelectRow indexPath: IndexPath,
cellViewModel: NCBaseCellViewModel) -> Bool {
// Handle tap event
return false
}
/// Handle cell tap events
/// - Parameters:
/// - viewModel: viewModel
/// - viewController: viewController
/// - tableView: tableView
/// - indexPath: indexPath
/// - viewModel: CellViewModel
/// - Returns: Whether the app handles the event [YES: SDK won't process, NO: SDK handles]
- (BOOL)searchFriendsViewModel:(NCSearchFriendsViewModel *_Nonnull)viewModel
viewController:(UIViewController*_Nonnull)viewController
tableView:(UITableView *_Nonnull)tableView
didSelectRow:(NSIndexPath *_Nonnull)indexPath
cellViewModel:(NCBaseCellViewModel *_Nonnull)cellViewModel {
}