自定义通讯录 UI
更新时间: 2024/07/26 13:39:23
IM UIKit 通讯录模块(NEContactUIKit
)提供通讯录界面的 UI 自定义配置项目配置项,助您快速实现该界面的 UI 个性化定制。
通讯录模块(NEContactUIKit
)提供以下两种方式对通讯录的 UI 进行个性化定制。
-
通过接口配置的方式自定义 UI。
-
通过源码修改的方式自定义 UI。
如果接口中的配置项满足您的界面个性化需求,请优先使用接口配置方式。
自定义功能描述
UI 元素自定义
通讯录界面可自定义的 UI 元素包括但不限于下图中的标注项。
NEKitContactConfig
是整个通讯录的配置文件,其中 UI 实例化对象类型为 ContactUIConfig
。
您可以通过 ContactUIConfig
类中的个性化配置项,对通讯录的 UI 样式进行修改,个性化配置项具体如下:
属性 | 类型 | 说明 |
---|---|---|
showTitleBar |
Bool | 是否展示标题栏。 |
showTitleBarRightIcon |
Bool | 是否展示标题栏的最右侧图标,具体自定义示例请参考下文的 隐藏标题栏搜索按钮和添加好友按钮。 |
showTitleBarRight2Icon |
Bool | 是否展示标题栏的次最右侧图标,具体自定义示例请参考下文的 隐藏标题栏搜索按钮和添加好友按钮。 |
titleBarRightRes |
UIImage | 标题栏的最右侧图标。 |
titleBarRight2Res |
UIImage | 标题栏的次最右侧图标。 |
titleBarRightClick |
() -> Void | 标题栏最右侧按钮单击事件。 |
titleBarRight2Click |
() -> Void | 标题栏次最右侧按钮单击事件。 |
title |
String | 标题栏文案。 |
titleColor |
UIColor | 标题栏字体颜色,具体自定义示例请参考下文的 自定义标题栏。 |
showHeader |
Bool | 是否在通讯录界面显示头部模块,具体自定义示例请参考下文的 隐藏头部模块。 |
headerData |
([ContactHeadItem]) -> Void | 头部模块的数据,如果不为空,则覆盖已有数据。 |
+
contactProperties |
ContactProperties | 通讯录好友列表中 UI 个性化定制属性设置,包括好友昵称的字体、好友头像、索引字体、颜色等。 |
friendItemClick |
(ContactInfo, IndexPath) -> Void | 好友列表的单击事件。 |
headerItemClick |
(ContactInfo, IndexPath) -> Void | 头部模块的单击事件。 |
customController |
(NEBaseContactsViewController) -> Void | 通讯录列表的视图控制器回调,回调中会返回通讯录列表的视图控制器。 |
界面布局自定义
除了界面的 UI 元素,您也可对界面的布局进行自定义。在 NEContactUIKit
模块中,通讯录主界面是基于 UITableview
的封装,主要布局集中在 NEBaseContactTableViewCell
中。
NEBaseContactTableViewCell
是一个子类,继承于 NEBaseContactViewCell
,如果需要修改 Cell 样式可以在 NEBaseContactTableViewCell
中修改或者自定义 Cell 样式。
不建议直接修改 NEBaseContactTableViewCell
,因为还存在其他类继承于 NEBaseContactTableViewCell
。
通讯录界面的默认布局如下图所示:
该界面各视图的说明如下:
属性 |
类型 | 说明 |
---|---|---|
titleBarView |
UIView | 通讯录列表界面标题,可通过 navigationView 来获取视图进行样式修改。 |
navigationView |
TabNavigationView | 通讯录列表界面标题视图,可在子类直接获取视图进行样式修改,具体自定义示例请参考下文的 自定义标题栏。 |
bodyTopView |
UIView | 好友列表上方的小块视图,可在子类直接获取视图进行样式修改。用于在通讯录列表和顶部标题中间增加新的 UI 元素,具体自定义示例请参考下文的 通讯录列表顶部添加扩展视图。 |
bodyView |
UIView | 通讯录列表界面的内容视图,可在子类直接获取视图进行样式修改。布局中包含 brokenNetworkView 错误提示视图和 contentView 列表视图。 |
brokenNetworkView |
NEBrokenNetworkView | 通讯录列表界面错误提示视图,可在子类直接获取视图进行样式修改。 |
contentView |
UIView | 通讯录列表界面的列表视图,可在子类直接获取视图进行样式修改。布局中包含 tableView 列表和 emptyView 空数据提示视图。 |
tableView |
UITableView | 通讯录界面的列表,可自定义单元格,实现数据的自定义展示,具体自定义示例请参考下文的 自定义单元格。 |
emptyView |
NEEmptyDataView | 通讯录列表界面空数据提示视图,可在子类直接获取视图进行样式修改。 |
bodyBottomView |
UIView | 好友列表底部的小块视图,可在子类直接获取视图进行样式修改,用于在好友列表底部增加新的 UI 元素,具体自定义示例请参考下文的 通讯录列表底部添加扩展视图。 |
通过配置项自定义 UI 示例
通讯录的个性化 UI 样式需要在通讯录界面加载之前配置,例如您可以在 IMKitClient
的 login
方法中设置个性化定制属性。
修改通讯录好友标题字体颜色和大小
-
示例代码
SwiftSwift
// 修改通讯录好友标题大小 NEKitContactConfig.shared.ui.contactProperties.itemTitleSize = 28 /// 修改通讯录好友标题颜色 NEKitContactConfig.shared.ui.contactProperties.itemTitleColor = UIColor.red
Objective-Cobjc
//修改通讯录好友标题大小 NEKitContactConfig.shared.ui.contactProperties.itemTitleSize = 28; //修改通讯录好友标题颜色 NEKitContactConfig.shared.ui.contactProperties.itemTitleColor = [UIColor redColor];
-
效果对比
默认 自定义后
隐藏标题栏搜索按钮和添加好友按钮
-
示例代码
SwiftSwift
//隐藏搜索按钮 NEKitContactConfig.shared.ui.showTitleBarRight2Icon = false //隐藏添加好友按钮 NEKitContactConfig.shared.ui.showTitleBarRightIcon = false
Objective-Cobjc
//隐藏搜索按钮 NEKitContactConfig.shared.ui.showTitleBarRight2Icon = NO; //隐藏添加好友按钮 NEKitContactConfig.shared.ui.showTitleBarRightIcon = NO;
-
效果对比
默认 自定义后
修改通讯录间隔线颜色
-
示例代码
SwiftSwift
NEKitContactConfig.shared.ui.contactProperties.divideLineColor = UIColor.red
Objective-Cobjc
NEKitContactConfig.shared.ui.contactProperties.divideLineColor = [UIColor redColor];
-
效果对比
默认 自定义后
隐藏头部模块
-
示例代码
SwiftSwift
NEKitContactConfig.shared.ui.showHeader = false
Objective-Cobjc
NEKitContactConfig.shared.ui.showHeader = NO;
-
效果对比
默认 自定义后
通过源码自定义 UI
NEBaseContactsViewController
为通讯录的实现类。具体的方法如下:
方法 | 入参类型 | 说明 |
---|---|---|
loadData |
无 | 加载通讯录主界面数据 |
goToFindFriend |
无 | 添加好友事件 |
searchContact |
无 | 搜索事件 |
onFriendChanged |
User | 好友状态发生变化的回调 |
onBlackListChanged |
无 | 黑名单变化的回调 |
onUserInfoChanged |
无 | 用户个人信息发生变化回调 |
自定义单元格(ContactTableViewCell)
用户可自定义单元格,实现数据的自定义展示。
实现步骤与示例代码(Swift),以通用皮肤为例:
-
继承 ContactTableViewCell 类,实现自定义单元格,对数据进行展示。
swift
public class CustomContactTableViewCell: ContactTableViewCell { private lazy var onlineView: UIImageView = { let notify = UIImageView() notify.translatesAutoresizingMaskIntoConstraints = false notify.image = UIImage(named: "about_yunxin") notify.isHidden = true return notify }() override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(onlineView) NSLayoutConstraint.activate([ onlineView.rightAnchor.constraint(equalTo: avatarImage.rightAnchor), onlineView.bottomAnchor.constraint(equalTo: avatarImage.bottomAnchor), onlineView.widthAnchor.constraint(equalToConstant: 12), onlineView.heightAnchor.constraint(equalToConstant: 12), ]) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 根据数据模型设置 cell 内容 override public func setModel(_ model: ContactInfo) { super.setModel(model) onlineView.isHidden = false } }
-
继承 ContactsViewController 类,实现自定义表格。
swift
public class CustomContactsViewController: ContactsViewController, ContactsViewControllerDelegate { override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) delegate = self // 自定义 cell, [ContactCellType.ContactCutom.rawValue: 需要注册的自定义 UI 类型] // 自定义 cell 的注册字典需要在 viewDidLoad 之前完成初始化 cellRegisterDic[ContactCellType.ContactCutom.rawValue] = CustomContactTableViewCell.self } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override public func viewDidLoad() { super.viewDidLoad() ... } // 父类加载完数据后会调用此方法,可在此对数据进行二次处理 public func onDataLoaded() { viewModel.contacts[1].contacts.forEach { info in info.contactCellType = ContactCellType.ContactCutom.rawValue } } }
onDataLoaded
方法调用时,表明父类已完成数据的加载,数据存放在viewModel.contacts
(类型为[ContactSection]
)列表中,数据模型定义为:swift
/* 通讯录 section 数据模型 // initial: tableView 对应 section 的标题 // contacts: tableView 对应 section 的数据 */ public class ContactSection { public var initial: String public var contacts: Array = [ContactInfo]() init(initial: String, contacts: [ContactInfo]) { self.initial = initial self.contacts = contacts } } /* 通讯录 cell 数据模型 // contactCellType: 自定义 UI 类型,其在注册会话列表 cell 时作为 key 与自定义 cell 进行绑定 // localExtension: 本地扩展字段,可根据业务需求添加数据,与 contactCellType 结合可实现多种自定义 cell 的展示 */ public class ContactInfo { ... public var user: User? public var contactCellType = ContactCellType.ContactPerson.rawValue public var router = ContactPersonRouter public var isSelected = false public var headerBackColor: UIColor? public var localExtension: [String: Any]? }
需要在
viewDidLoad
之前完成会话列表cell
注册字典(cellRegisterDic
)的初始化,cellRegisterDic
的类型为[Int : NEBaseContactTableViewCell.Type]
,其中 key 对应通讯录 cell 数据模型中的 contactCellTypee,需要在此处与其对应的自定义 UI 类型进行绑定,从而实现不同类型的自定义单元格的对应展示。
例如在用户头像下 添加小标,如下图所示:
默认 | 自定义后 |
---|---|
自定义标题栏(navigationView)
自 V9.6.1 起,自定义导航栏需要使用 customNavigationView
来实现,V9.6.5 更名为 navigationView
。
-
示例代码
SwiftSwift
// 修改标题 navigationView.navTitle.text = "title" // 修改右侧按钮文案 navigationView.setMoreButtonTitle("clear") // 修改右侧按钮文案颜色 navigationView.moreButton.setTitleColor(.red, for: .normal) // 修改右侧按钮单击事件 navigationView.moreButton.addTarget(self, action: #selector(clearMessage), for: .touchUpInside)
Objective-Cobjc
// 修改标题 navigationView.navTitle.text = @"title"; // 修改右侧按钮文案 [navigationView setMoreButtonTitle:@"clear"]; // 修改右侧按钮文案颜色 [navigationView.moreButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; // 修改右侧按钮单击事件 [navigationView.moreButton addTarget:self action:@selector(clearMessage) forControlEvents:UIControlEventTouchUpInside];
-
效果对比
默认 自定义后 单击查看 V9.6.1 之前版本实现自定义标题栏按钮的 Swift 示例代码。
Swift
public class CustomContactsViewController: ContactsViewController, ContactsViewControllerDelegate { override public func viewDidLoad() { super.viewDidLoad() ... } // 自定义标题栏右侧按钮 override public func addNavbarAction() { let addItem = UIBarButtonItem( image: UIImage(named: "mine_collection"), style: .plain, target: self, action: #selector(addItemAction) ) addItem.tintColor = UIColor(hexString: "333333") let searchItem = UIBarButtonItem( image: UIImage(named: "mine_setting"), style: .plain, target: self, action: #selector(searchItemAction) ) searchItem.imageInsets = UIEdgeInsets(top: 0, left: 35, bottom: 0, right: 0) searchItem.tintColor = UIColor(hexString: "333333") if NEKitContactConfig.shared.ui.hiddenRightBtns { return } else { if NEKitContactConfig.shared.ui.hiddenSearchBtn { navigationItem.rightBarButtonItems = [addItem] } else { navigationItem.rightBarButtonItems = [addItem, searchItem] } } } @objc private func addItemAction() { print("addItemAction") } @objc private func searchItemAction() { print("searchItemAction") } }
示例代码中标题栏为通讯录页面的系统标题栏,用户可自定义其中的 UI 元素,包括但不限于标题、搜索按钮及其单击事件和添加按钮及其单击事件。
-
效果对比
默认 自定义后
通讯录列表顶部添加扩展视图
-
示例代码(Swift)
swift
public class CustomContactsViewController: ContactsViewController, ContactsViewControllerDelegate { public lazy var customTopView: CustomView = { let view = CustomView(frame: CGRect(x: 0, y: 10, width: NEConstant.screenWidth, height: 40)) view.backgroundColor = .blue return view }() override public func viewDidLoad() { super.viewDidLoad() ... // 顶部 bodyTopView 中添加自定义 view(需要设置 bodyTopView 的高度) customTopView.btn.setTitle("通过重写方式添加" , for: .normal) bodyTopView.addSubview(customTopView) bodyTopViewHeight = 80 } }
示例代码中
bodyTopView
为通讯录列表顶部预留的扩展视图,bodyTopViewHeight
为该扩展视图的高度,更改此变量会刷新页面布局。 -
效果对比
默认 自定义后
通讯录列表底部添加扩展视图
-
示例代码(Swift)
swift
public class CustomContactsViewController: ContactsViewController, ContactsViewControllerDelegate { override public func viewDidLoad() { super.viewDidLoad() ... // 底部 bodyBottomView 中添加自定义 view(需要设置 bodyBottomView 的高度) customBottomView.btn.setTitle("通过重写方式添加", for: .normal) bodyBottomView.addSubview(customBottomView) bodyBottomViewHeight = 60 } }
示例代码中
bodyBottomView
为通讯录列表底部预留的扩展视图,bodyBottomViewHeight
为该扩展视图的高度,更改此变量会刷新页面布局。 -
效果对比
默认 自定义后