IM 自定制的思路:例子是 NIMKit 的源码
有展现音讯的列表
- NIMKit 设计挺好的
面向协议,结构上的便于替换
本文主要讨论,展现音讯
IM 自定制,一般的了解是
自定义音讯,分为数据和界面,两部分
- 自定义音讯的数据结构
// 自定义音讯解析
NIMCustomObject.registerCustomDecoder(IMMsgDecoder())
- 自定义音讯的界面
咱们看到的谈天记录,便是一个音讯列表 , UITableView
// 布局管理器
NIMKit.shared().registerLayoutConfig(IMCellLayoutConfig())
场景,谈天会话界面,需求一套 IM 界面
语音房里边,的半屏幕谈天界面,需求另外一套款式的 IM 界面
即,一款 app 内,一起存在两种 IM 谈天界面
思路一: 简略的,换装备
默许这样注册
// 布局管理器
NIMKit.shared().registerLayoutConfig(IMCellLayoutConfig())
新的谈天款式界面中,
出现,就换新的装备,
消失,就恢复本来的装备
class SessionChatVC: NIMSessionViewController{
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NIMKit.shared().registerLayoutConfig(IMCellLayoutConfigDjz())
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NIMKit.shared().registerLayoutConfig(IMCellLayoutConfig())
}
}
作用是,把文本音讯的文字色彩改了
class IMCellLayoutConfigDjz: NIMCellLayoutConfig{
// 重写,自定义cell音讯 , contentView
override func cellContent(_ model: NIMMessageModel!) -> String! {
guard model.message.messageType != .text else {
// 看这一行,够了
return NSStringFromClass(NIMSessionTextContentViewDJZ.self)
}
guard model.message.messageType == .custom,
let customAttachment = model.message.messageObject as? NIMCustomObject,
let attachment = customAttachment.attachment
else {
return super.cellContent(model)
}
if attachment.isKind(of: IMGiftsAttachment.self) {
return NSStringFromClass(IMGiftContentView.self)
}else if attachment.isKind(of: IMGifImageAttachment.self) {
return NSStringFromClass(IMGifImageContentView.self)
}
else{
return NSStringFromClass(IMChatUpContentView.self)
}
}
}
NIMSessionTextContentViewDJZ 其他的,与 NIMKit 自带的 NIMSessionTextContentView,相同
@implementation NIMSessionTextContentViewDJZ
- (void)refresh:(NIMMessageModel *)data {
[super refresh:data];
// 音讯解码 默许: self.model.message.text
NSString *text = [IMMessageTool imMessageTextBase64Decoded:self.model.message];
NIMKitSetting *setting = [[NIMKit sharedKit].config setting:data.message];
// 看这一行
// 出于演示,例子十分的简略
self.textLabel.textColor = UIColor.redColor;
// self.textLabel.textColor = setting.textColor;
self.textLabel.font = setting.font;
[self.textLabel nim_setText:text];
[self.bubbleImageView setHidden: true];
}
@end
思路 2 : 复杂些, 触及的源代码,多一些
建立谈天界面的子类 NIMSessionViewController
@interface NIMDjzSessionViewCtrl: NIMSessionViewController
@end
简略的,修正谈天界面的背景色: cell 的背景色
谈天界面,款式 A, 背景色 AA
@implementation NIMSessionViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[[NIMKit sharedKit] config] setCellBackgroundColor: NIMKit_UIColorFromRGB(0xf5f5f5)];
}
@end
语音房的谈天界面,款式 Z, 背景色 ZZ
@implementation NIMDjzSessionViewCtrl
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear: animated];
[[[NIMKit sharedKit] config] setCellBackgroundColor: bgColor];
}
@end
修正 TableView 与根视图的背景色
语音房的谈天界面
@implementation NIMDjzSessionViewCtrl
- (void)setupTableView{
self.view.backgroundColor = bgColor;
self.tableView = [[UITableView alloc] initWithFrame: CGRectMake(0, 52, 375, 233) style:UITableViewStylePlain];
self.tableView.backgroundColor = bgColor;
// ...
}
@end
消除语音房的谈天界面,的背景气泡
运用 NIMAdvancedMessageCellDjz
,而不是 NIMAdvancedMessageCell
NIMAdvancedMessageCellDjz 与 NIMAdvancedMessageCell 的区别,在于
@implementation NIMAdvancedMessageCellDjz
- (void)refreshBubblesBackgroundView{
// 躲藏气泡
[self.bubblesBackgroundView setHidden: YES];
}
@end
往上推导,
为了运用 NIMAdvancedMessageCellDjz
,
需求运用 NIMMessageCellFactoryDeng
@implementation NIMMessageCellFactoryDeng
- (NIMMessageCell *)cellInTable:(UITableView*)tableView
forMessageMode:(NIMMessageModel *)model
{
id<NIMCellLayoutConfig> layoutConfig = [[NIMKit sharedKit] layoutConfig];
NSString *identity = [layoutConfig cellContent:model];
NIMMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:identity];
if (!cell) {
// 留意这一行
NSString *clz = @"NIMAdvancedMessageCellDjz";
[tableView registerClass:NSClassFromString(clz) forCellReuseIdentifier:identity];
cell = [tableView dequeueReusableCellWithIdentifier:identity];
}
return (NIMMessageCell *)cell;
}
@end
NIMMessageCellFactoryDeng 与 NIMMessageCellFactory 相似
风格,就如上面
持续推导,
为了运用 NIMMessageCellFactoryDeng
,
需求运用 NIMSessionTableAdapterDeng
@interface NIMSessionTableAdapterDeng()
@property (nonatomic,strong) NIM_djz_MessageCellFactory *cellFactory;
@end
@implementation NIMSessionTableAdapterDeng
- (instancetype)init
{
self = [super init];
if (self) {
_cellFactory = [[NIMMessageCellFactoryDeng alloc] init];
}
return self;
}
@end
NIMSessionTableAdapterDeng 与 NIMSessionTableAdapter 相似
持续推导,
为了运用 NIMSessionTableAdapterDeng
,
需求调整 NIMSessionConfigurator
的源代码
增加属性
@interface NIMSessionConfigurator()
@property (nonatomic,strong) NIM_djz_SessionTableAdapter *tableAdapterDeng;
@end
增加办法
@implementation NIMSessionConfigurator
- (void)setupDeng:(NIMSessionViewController *)vc{
// 上面的,同 setup 办法
_tableAdapterDeng = [[NIMSessionTableAdapterDeng alloc] init];
_tableAdapterDeng.interactor = _interactor;
_tableAdapterDeng.delegate = vc;
vc.tableView.delegate = _tableAdapterDeng;
vc.tableView.dataSource = _tableAdapterDeng;
[vc setInteractor:_interactor];
}
@end
向上推导,
最后,
语音房的半屏幕的谈天界面 , 款式 Z
调用 setupDeng
, 打通
@implementation NIMAdvancedMessageCellDjz
- (void)setupConfigurator{
self.configurator = [[NIMSessionConfigurator alloc] init];
// 留意这一行
[self.configurator setupDeng:self];
BOOL needProximityMonitor = [self needProximityMonitor];
[[NIMSDK sharedSDK].mediaManager setNeedProximityMonitor:needProximityMonitor];
}
@end
NIMKit 并不难,便是功用挺多的,
为了解除耦合,调用绕来绕去的
已经倒着整理了一遍
再来顺着,整理一遍
咱们看到,谈天视图里边,
有一个 tableView
@interface NIMSessionViewController
@property (nonatomic, strong) UITableView *tableView;
@end
谈天视图里边的装备代码
@implementation NIMSessionViewController
- (void)viewDidLoad {
[super viewDidLoad];
//会话相关逻辑装备器装置
[self setupConfigurator];
}
- (void)setupConfigurator
{
_configurator = [[NIMSessionConfigurator alloc] init];
[_configurator setup:self];
}
@end
NIMSessionConfigurator 里边,
设置了谈天会话界面 NIMSessionViewController 的列表 TableView, 的 dataSource
@implementation NIMSessionConfigurator
- (void)setup:(NIMSessionViewController *)vc
{
vc.tableView.delegate = _tableAdapter;
vc.tableView.dataSource = _tableAdapter;
}
@end
咱们看到的一行行谈天记录,自然是 dataSource
这样。两头就打通了