IM 自定制的思路:例子是 NIMKit 的源码

本文详细介绍了如何在NIMKit框架下实现IM聊天界面的自定义,包括自定义消息数据结构、界面展示及聊天界面的样式切换。通过注册布局管理器和消息解析器,可以实现不同场景下的聊天界面定制,例如改变文字颜色、背景色,甚至消除气泡等。此外,还展示了如何创建聊天界面子类,以实现更复杂的样式修改,如修改聊天界面的背景色、TableView的背景色以及使用自定义消息Cell。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 发消息,有发送的触发界面,一般是输入框,及相关按钮

有展示消息的列表

  • 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 = [MMessageTool 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

这样。两边就打通了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值