有奖捉虫:行业应用 & 管理与支持文档专题 HOT
TUIKit 默认实现了文本、图片、语音、视频、文件等基本消息类型的发送和展示,如果这些消息类型满足不了您的需求,您可以新增自定义消息类型。

基本消息类型

消息类型
显示效果图
文本类消息
?
?
?
图片类消息
?
?
?
语音类消息
?
?
?
视频类消息
?
?
?
文件类消息
?
?
?

自定义消息

如果基本消息类型不能满足您的需求,您可以根据实际业务需求自定义消息。下文以发送一条可跳转至浏览器的超文本作为自定义消息为例,帮助您快速了解实现流程。 TUIKit 内置的自定义消息样式如下图所示:
?
?
?
注意:
TUIKit 在 7.4.4643 版本重新设计了一套自定义消息注册机制,新旧方案变动较大,但可以支持不同的 UI 样式,建议您升级到 7.4.4643 版本。本文将以 7.4.4643 版本为例讲解。 ?
如果您使用的依然是 5.8.1668 以下版本,可参见文档 iOS(5.8.1668以下版本适用)

展示自定义消息

TUIKit 内置的自定义消息 cell 元素如下图所示:
?
?
?
您可以在 TUIMessageBaseDataProvider.monRecvNewMessage 函数内接收自定义消息。 收到的自定义消息最终会以 Cell 的形式展示在消息列表中,Cell 绘制所需的数据我们称之为 CellData
下面我们分步骤讲解下如何展示自定义消息。

创建自定义 CellData

1. TUIChat/TUIChat/BaseCellData/Custom 文件夹下新建 TUILinkCellData.hTUILinkCellData.m 文件,继承自TUIMessageCellData ,用于存储显示的文字和跳转的链接。
示例代码如下:
@interface TUILinkCellData : TUIMessageCellData ??
?
@property NSString *text;
@property NSString *link; ??
?
@end
2. 重写父类的getCellData: 方法。用于把 V2TIMMessage 转换成消息列表 Cell 的绘制数据 TUILinkCellData。 示例代码如下:
@implementation TUILinkCellData ??
+ (TUIMessageCellData *)getCellData:(V2TIMMessage *)message {
?? ? ? NSDictionary *param = [NSJSONSerialization JSONObjectWithData:message.customElem.data options:NSJSONReadingAllowFragments error:nil];
TUILinkCellData *cellData = [[TUILinkCellData alloc] initWithDirection:message.isSelf ? MsgDirectionOutgoing : MsgDirectionIncoming]; ?? ? ?
cellData.innerMessage = message; ?? ? ?
cellData.msgID = message.msgID; ?? ? ?
cellData.text = param[@"text"]; ?? ? ?
cellData.link = param[@"link"]; ?? ? ?
cellData.avatarUrl = [NSURL URLWithString:message.faceURL]; ?? ? ?
return cellData; ??
} ??
@end ? ?
3. 重写父类的getDisplayString:方法。用于把 V2TIMMessage 转换成会话列表 lastMsg 的展示文本信息。 会话列表 lastMsg 展示文本指的是当用户停留在会话列表,每个会话 cell 会显示当前会话最后一条消息。如下图所示:
??
?
?
示例代码如下:
@implementation TUILinkCellData
?
+ (NSString *)getDisplayString:(V2TIMMessage *)message {
NSDictionary *param = [NSJSONSerialization JSONObjectWithData:message.customElem.data options:NSJSONReadingAllowFragments error:nil];
return param[@"text"];
}
?
@end

创建自定义 Cell

1. TUIChat//UI_Classic/Cell/Custom 文件夹下新建 TUILinkCell.hTUILinkCell.m 文件,继承自 TUIMessageCell ,用于绘制 TUILinkCellData 数据。
示例代码如下:
@interface TUILinkCell : TUIMessageCell
@property UILabel *myTextLabel; // 展示文本
@property UILabel *myLinkLabel; // 链接跳转文本
- (void)fillWithData:(TUILinkCellData *)data; // 绘制 UI
@end
2. 重写父类 initWithStyle:reuseIdentifier: 方法,创建 myTextLabel 和 myLinkLabel 文本展示对象,并添加至 container 容器。
示例代码如下:
@implementation TUILinkCell
// 初始化控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.myTextLabel = [[UILabel alloc] init];
[self.container addSubview:self.myTextLabel];
self.myLinkLabel = [[UILabel alloc] init];
self.myLinkLabel.text = @"查看详情>>";
[self.container addSubview:_myLinkLabel];
}
return self;
}
@end
3. 重写父类?fillWithData:?方法,在?TUILinkCell?中自定义展示?TUILinkCellData?数据。
示例代码如下:
@implementation TUILinkCell
// 根据 cellData 绘制 cell
- (void)fillWithData:(TUILinkCellData *)data;
{
[super fillWithData:data];
self.myTextLabel.text = data.text;
}
@end
4. 重写父类 layoutSubviews 方法,自定义控件的布局。
示例代码如下:
// 设置控件坐标
- (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
5. 重写父类的 getContentSize: 方法,用于计算 cellData 内容所占绘制区域的大小。 示例代码如下:
+ (CGSize)getContentSize:(TUIMessageCellData *)data {
NSAssert([data isKindOfClass:TUILinkCellData.class], @"data must be kind of TUILinkCellData");
TUILinkCellData *linkCellData = (TUILinkCellData *)data;
CGFloat textMaxWidth = 245.f;
CGRect rect = [linkCellData.text boundingRectWithSize:CGSizeMake(textMaxWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]}
context:nil];
CGSize size = CGSizeMake(textMaxWidth + 15, rect.size.height + 56);
return size;
}

将您的自定义 Cell 和 CellData 注册进 TUIChat

注意:
每一种自定义消息都必须有唯一的 businessID,区分大小写,不可跟其他自定义消息的 businessID 重复。TUIChat 需要根据此 businessID 找到对应的自定义消息。
新增自定义消息的 businessID 也不能和 TUIKit 内置自定义消息的 businessID 重复。
在 App 初始化时,需要您通过 TUIChatConfig.hregisterCustomMessage 函数里主动注册 cellcellData 信息。
示例代码如下:
// 自定义消息 businessID(注意不能重复)
#define BussinessID_TextLink @"text_link"
?
/** 向 TUIChat 注册自定义消息。三个参数分别为
* @param businessID 自定义消息 businessID * @param messagellClass 自定义消息 NSString 类型 * @param messageCellDataClassName 自定义消息 NSString 类型
*/
- (void)registerCustomMessageCell {
[TUIChatConfig.defaultConfig registerCustomMessage:BussinessID_TextLink
messageCellClassName:@"TUILinkCell"
messageCellDataClassName:@"TUILinkCellData"
];
}
除此之外,TUIChatConfigs 还提供了 registerCustomMessage 方法的另一个方法,支持注册简约版 UI 下的自定义消息。详情可参见 TUIChatConfig.h 文件。

发送自定义消息

如下图所示,自定义消息发送按钮主要由文本title和图片image组成。您可以通过在 TUIChatDataProvidercustomInputMoreMenus属性中新增 TUIInputMoreCellData对象来添加自定义按钮。
您可以通过设置TUIInputMoreCellDatatitleimage属性来自定义您想展示的文字和图片信息;如果您想调整按钮的展示顺序,可以设置 priority属性,其中priority值越大按钮越靠前;您也可以设置onClicked来响应该按钮的点击事件,实现自己的业务逻辑。
?
?
?
示例代码如下:
@implementation TUIChatDataProvider
- (NSArray<TUIInputMoreCellData *> *)customInputMoreMenus {
? ? if (_customInputMoreMenus == nil) {
? ? ? ? NSMutableArray *arrayM = [NSMutableArray array];
? ? ? ? if (TUIChatConfig.defaultConfig.enableWelcomeCustomMessage) {
? ? ? ? ? ? // Link
? ? ? ? ? ? __weak typeof(self) weakSelf = self;
? ? ? ? ? ? TUIInputMoreCellData *linkData = [[TUIInputMoreCellData alloc] init];
? ? ? ? ? ? linkData.priority = 0;
? ? ? ? ? ? linkData.title = TIMCommonLocalizableString(TUIKitMoreLink);
? ? ? ? ? ? linkData.image = TUIChatBundleThemeImage(@"chat_more_link_img", @"chat_more_link_img");
? ? ? ? ? ? linkData.onClicked = ^(NSDictionary *actionParam) {
? ? ? ? ? ? ? NSString *text = TIMCommonLocalizableString(TUIKitWelcome);
? ? ? ? ? ? ? NSString *link = TUITencentCloudHomePageEN;
? ? ? ? ? ? ? NSString *language = [TUIGlobalization tk_localizableLanguageKey];
? ? ? ? ? ? ? if ([language containsString:@"zh-"]) {
? ? ? ? ? ? ? ? ? link = TUITencentCloudHomePageCN;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? NSError *error = nil;
? ? ? ? ? ? ? NSDictionary *param = @{BussinessID : BussinessID_TextLink, @"text" : text, @"link" : link};
? ? ? ? ? ? ? NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:&error];
? ? ? ? ? ? ? if (error) {
? ? ? ? ? ? ? ? ? NSLog(@"[%@] Post Json Error", [weakSelf class]);
? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? }
? ? ? ? ? ? ? V2TIMMessage *message = [TUIMessageDataProvider getCustomMessageWithJsonData:data];
? ? ? ? ? ? ? if ([weakSelf.delegate respondsToSelector:@selector(dataProvider:sendMessage:)]) {
? ? ? ? ? ? ? ? ? [weakSelf.delegate dataProvider:weakSelf sendMessage:message];
? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? [arrayM addObject:linkData];
? ? ? ? }
? ? ? ? _customInputMoreMenus = arrayM;
? ? }
? ? return _customInputMoreMenus;
}
@end
?


http://www.vxiaotou.com