项目中集成了环信即时通讯,但是项目需要自定义消息类型,看环信发送消息方法,在发送消息的时候可以附加自定义的内容。

下面我将拿微信中名片为例来介绍:

确定发送方式:

首先需要与Android开发人员沟通发送什么类型消息的时候传递,环信sdk中封装的任何消息都是可以附加自定义内容的,在这里我们定义的是在发送文本消息的时候传递,也就是说发送自定义的名片等于发送的是文本消息。

确定字段:

先看自定义消息中所显示的内容:头像、昵称、效应号;我们定义的字典字段为:nickname、user_pic、num这三个,由于在点击这条消息的时候需要跳转到这个人的个人信息页面,所有又应该加上user_id,我们项目中所自定义的 消息不只一种还有其他的消息,这样我们又需要加上一个type来区分,最终附加字段为: nickname、user_pic、num、user_id、type

发送消息:

在选择完联系人后,回调信息到聊天页面发送消息

NSDictionary *dict = @{@"user_id":user_id,@"nickname":nickname,@"user_pic":user_pic,@"num":number,@"type":@"0"};
        [self sendTextMessage:@"[效应名片]" withExt:dict];

定义UI

每条消息都是显示都是一个Cell,Cell要继承EaseBaseMessageCell,聊天的Cell都是有气泡的,显示的信息都是在气泡上,也就是说,我们只需要定义一个View然后放到气泡上,并且修改气泡的大小,就可以了。

  1. 定义UI页面
    创建一个创建一个继承UIView的类,在这个类上定义自己需要的UI,也就是下图所显示的内容


下面是我定义的LCChatXiaoYingCardView.m代码

@interface LCChatXiaoYingCardView ()
/**
 头像
 */
@property (strong, nonatomic)  UIImageView *iconImageView;
/**
 昵称
 */
@property (strong, nonatomic)  UILabel *nameLabel;
/**
 效应号
 */
@property (strong, nonatomic)  UILabel *numberLabel;

@end

@implementation LCChatXiaoYingCardView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self loadView];
    }
    return self;
}

- (void)loadView{
    _iconImageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 5, 30, 30)];
    [self addSubview:_iconImageView];

    self.nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(50, 5, 100, 15)];
    _nameLabel.font = [UIFont systemFontOfSize:13];
    [self addSubview:self.nameLabel];

    _numberLabel = [[UILabel alloc]init];
    [self addSubview:_numberLabel];
    _numberLabel.font = [UIFont systemFontOfSize:12];
    _numberLabel.textColor = [UIColor grayColor];
    [self.numberLabel makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_iconImageView.right).offset(10);
        make.bottom.equalTo(_iconImageView.bottom).offset(0);
        make.width.offset(100);
    }];

    UIView *lineView = [[UIView alloc]initWithFrame:CGRectMake(0, 45, 180, 0.5)];
    lineView.backgroundColor = [UIColor groupTableViewBackgroundColor];
    [self addSubview:lineView];

    UILabel *myLabel = [[UILabel alloc]init];
    [self addSubview:myLabel];
    myLabel.text = @"效应名片";
    [myLabel makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(lineView.bottom).offset(0);
        make.left.equalTo(_iconImageView.left);
        make.height.offset(15);
        make.width.offset(50);
    }];
    myLabel.font = [UIFont systemFontOfSize:11];
}

- (void)setExtInfo:(LCChatExtModel *)extInfo
{
    [_iconImageView sd_setImageWithURL:[NSURL URLWithString:extInfo.user_pic] placeholderImage:[UIImage imageNamed:@"image"]];
    _nameLabel.text = extInfo.nickname;
    _numberLabel.text = [NSString stringWithFormat:@"效应号:%@",extInfo.num];
}

@end
  1. 自定义Cell
    创建一个继承于EaseBaseMessageCell的cell
    先重写EaseBaseMessageCell的initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier model:(id)model方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier model:(id<IMessageModel>)model
{
   self =  [super initWithStyle:style reuseIdentifier:reuseIdentifier model:model];
    if (self) {
        self.avatarSize = 35;//头像尺寸
        self.messageNameIsHidden = YES;//是否显示发送者昵称
        self.avatarCornerRadius = 3;//头像圆角大小
    }
    return self;
}

再重写setModel:(id)model方法

- (void)setModel:(id<IMessageModel>)model
{
    [super setModel:model];

    NSDictionary *dict = model.message.ext;   
    LCChatExtModel *extModel = [LCChatExtModel mj_objectWithKeyValues:dict]; 
    if (extModel.type == 0]) {//名片
        self.bubbleView.textLabel.hidden = YES;
        self.cardView.hidden = NO;
        self.cardView.extInfo = extModel;
        [self _updateStatusWithWidth:195 withHeight:70];
    }else{
        self.cardView.hidden = YES;
        self.bubbleView.textLabel.hidden = NO;
        [self removeConstraint:_bubbleViewH];
        [self removeConstraint:_bubbleViewW];
    }
}

设置气泡,在这里说明一下,我最开始应该是直接修改气泡的frame没有成功,然后看环信是使用NSLayoutConstraint来UI适配,所以在这里我也使用了NSLayoutConstraint约束来调整气泡大小

/**
 设置气泡
 */
- (void)_updateStatusWithWidth:(CGFloat)width withHeight:(CGFloat)height
{
    [self removeConstraint:_bubbleViewH];
    [self removeConstraint:_bubbleViewW];
    _bubbleViewW = [NSLayoutConstraint constraintWithItem:self.bubbleView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width];
    [self addConstraint:_bubbleViewW];

    _bubbleViewH = [NSLayoutConstraint constraintWithItem:self.bubbleView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height    ];
    [self addConstraint:_bubbleViewH];
    [self layoutIfNeeded];
}

重写cellHeightWithModel方法,该方法是定义在tableView中获取Cell高度的方法

+ (CGFloat)cellHeightWithModel:(id<IMessageModel>)model
{
    CGFloat surperHeight = [super cellHeightWithModel:model];
    NSDictionary *dict = model.message.ext;
    LCChatExtModel *extModel = [LCChatExtModel mj_objectWithKeyValues:dict];
    if (extModel.type == 0) {
        return surperHeight +55;
    }
    return surperHeight;
}
  1. 加载Cell
    定义一个继承EaseMessageViewController的类,以后跳转到聊天页面使用该类,那么如何将cell放到TableView上呢?环信已经开发这个接口,下面在类中实现EaseMessageViewControllerDelegate的方法就可以了

遵守协议

self.delegate = self;//EaseMessageViewControllerDelegate

实现EaseMessageViewControllerDelegate方法

/**
 设置自定义Cell
 */
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model{
    if (model.bodyType == EMMessageBodyTypeText ) {
        NSString *CellIdentifier = [LCChatXiaoYingCardCell cellIdentifierWithModel:model];
        LCChatXiaoYingCardCell *cardCell = (LCChatXiaoYingCardCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cardCell == nil) {
            cardCell = [[LCChatXiaoYingCardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
            cardCell.selectionStyle = UITableViewCellSelectionStyleNone;
            cardCell.delegate = self;
        }
        cardCell.model = model;
        return cardCell;
    }
    return nil;//如果不是自定义类型返回空
}
/**
 设置聊天高度
 */
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
        heightForMessageModel:(id<IMessageModel>)messageModel
                   withCellWidth:(CGFloat)cellWidth
{
    LCChatExtModel *extModel = [LCChatExtModel mj_objectWithKeyValues:messageModel.message.ext];
    if ([extModel.type == 0]) {
        return [LCChatXiaoYingCardCell cellHeightWithModel:messageModel] ;
    }
    return 0;//如果不是自定义类型返回0
}

到这里呢,整个自定义就结束了