Skip to content

TUIKit iOS自定义消息

whalehe edited this page Jun 14, 2019 · 3 revisions

iOS

TUIChatController 中, 每一条消息在内部都是存储为 TUIMessageCellData 或子类对象;当滑动消息列表时,再将  TUIMessageCellData  转换为 TUIMessageCell 用于显示。

通过设置 TUIChatController 回调 delegate,开发者可以控制具体的 TUIMessageCell 实例,达到定制消息的目的。

示例:

红色线框是客服发过来的一段自定义消息。 TUIKit 内部并没有实现这种现实效果,因此需要您自己实现。分析后可发现,只需在 TUIMessageCell 的 container 里,添加两个 UILabel ,即可达到显示效果。

Step 1: 实现一个自定义 cellData 类,继承自 TUIMessageCellData

我们定义一个 Data 类,用于存储显示的文字和链接

@inerface MyCustomCellData : TUIMessageCellData
@property NSString *text;
@property NSString *link;
@end

TUIMessageCellData 需要计算出显示内容的大小。否者对于自定义的 Cell, TUIChatController 不知道要预留多大的位置来显示。

@implement MyCustomCellData : TMessageCellData
- (CGSize)contentSize
{
    CGRect rect = [self.text boundingRectWithSize:CGSizeMake(300, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:15] } context:nil];
    CGSize size = CGSizeMake(ceilf(rect.size.width)+1, ceilf(rect.size.height));
    
    // 加上气泡边距
    size.height += 60;
    size.width += 20;
    
    return size;
}
@end

Step 2: 实现一个自定义cell类,继承自TUIMessageCell

TUIChatController 显示的消息都是 TUIMessageCell 及其子类,所以自定义的 cell 也需要继承自该类。

@interface MyCustomCell : TUIMessageCell
@property UILabel *myTextLabel;
@property UILabel *myLinkLabel;
@end

在实现文件中,我们需要创建出 myTextLabel 和 myLinkLabel 对象,并添加到 container 中。

@implementation MyCustomCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _myTextLabel = [[UILabel alloc] init];
        _myTextLabel.numberOfLines = 0;
        _myTextLabel.font = [UIFont systemFontOfSize:15];
        [self.container addSubview:_myTextLabel];
        
        _myLinkLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _myLinkLabel.text = @"查看详情>>";
        _myLinkLabel.font = [UIFont systemFontOfSize:15];
        _myLinkLabel.textColor = [UIColor blueColor];
        [self.container addSubview:_myLinkLabel];
        
        self.container.backgroundColor = [UIColor whiteColor];
        [self.container.layer setMasksToBounds:YES];
        [self.container.layer setBorderColor:[UIColor lightGrayColor].CGColor];
        [self.container.layer setBorderWidth:1];
        [self.container.layer setCornerRadius:5];
    }
    return self;
}

- (void)fillWithData:(MyCustomCellData *)data;
{
    [super fillWithData:data];
    self.customData = data;
    self.myTextLabel.text = data.text;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    self.myTextLabel.mm_top(10).mm_left(10).mm_flexToRight(10).mm_flexToBottom(50);
    self.myLinkLabel.mm_sizeToFit().mm_left(10).mm_bottom(10);
}
@end

Step 3: 注册 TUIChatController 回调

注册回调的目的是告诉 TUIChatController 改如何显示这个消息。需要实现两个回调:
1、收到消息时,将 TIMessage 转换为 TUIMessageCellData 对象;
2、在显示前将 TUIMessageCellData 转换为 TUIMessageCell 对象,用于最终显示。

@implement MyChatController
- (id)init
{
	self = [super init];
	// 初始化
	chat = [[TUIChatController alloc] initWithConversation:conv];
    [self addChildViewController:chat]; // 将聊天界面加到内部
    chat.delegate = self;	// 设置回调
    // 配置导航条
    ...
    
    return self;
}
// TChatController 回调函数
- (TUIMessageCellData *)chatController:(TUIChatController *)controller onNewMessage:(TIMMessage *)msg
{
    TIMElem *elem = [msg getElem:0];
    if([elem isKindOfClass:[TIMCustomElem class]]){
        MyCustomCellData *cellData = [[MyCustomCellData alloc] initWithDirection:msg.isSelf ? MsgDirectionOutgoing : MsgDirectionIncoming];
        cellData.text = @"欢迎欢迎欢迎欢迎";
        cellData.link = @"www.qq.com";
        return cellData;
    }
    return nil;
}

- (TUIMessageCell *)chatController:(TUIChatController *)controller onShowMessageData:(TUIMessageCellData *)data
{
    if ([data isKindOfClass:[MyCustomCellData class]]) {
        MyCustomCell *myCell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"];
        [myCell fillWithData:(MyCustomCellData *)data];
        return myCell;
    }
    return nil;
}

@end

发送自定义消息

TUIChatController 提供了发送消息接口,用户通过代码控制消息发送。发送的消息类型是 TUIMessageCellData 的子类。例如发送文本消息,可以创建一个 TUITextMessageCellData 对象。如果是发送自定义数据,需要初始化 innerMessage 属性,具体参考 ImSDK 文档 自定义消息

MyCustomCellData *cellData = [[MyCustomCellData alloc] initWithDirection:MsgDirectionOutgoing];       
cellData.innerMessage = [[TIMMessage alloc] init];
TIMCustomElem * custom_elem = [[TIMCustomElem alloc] init];
[cellData.innerMessage addElem:custom_elem];
[chatController sendMessage:cellData];